diff options
author | Bartosz Golaszewski <bartosz.golaszewski@linaro.org> | 2024-10-18 11:10:13 +0200 |
---|---|---|
committer | Bartosz Golaszewski <bartosz.golaszewski@linaro.org> | 2024-10-22 08:59:08 +0200 |
commit | 7b9b77a8bba9c1fd7bad3310dbf2cf382e1f8c25 (patch) | |
tree | e12d5111533a4371ab5f5010d5d4de02cb507a34 /drivers/gpio | |
parent | gpio: cdev: prepare gpio_desc_to_lineinfo() for being called from atomic (diff) | |
download | linux-7b9b77a8bba9c1fd7bad3310dbf2cf382e1f8c25.tar.xz linux-7b9b77a8bba9c1fd7bad3310dbf2cf382e1f8c25.zip |
gpiolib: add a per-gpio_device line state notification workqueue
In order to prepare the line state notification mechanism for working in
atomic context as well, add a dedicated, high-priority, ordered
workqueue to GPIO device which will be used to queue the events fron any
context for them to be emitted always in process context.
Reviewed-by: Kent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20241018-gpio-notify-in-kernel-events-v5-5-c79135e58a1c@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib-cdev.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.h | 4 |
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 0cba74381687..b242fdb1ad28 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2749,6 +2749,11 @@ int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt) gdev->chrdev.owner = THIS_MODULE; gdev->dev.devt = MKDEV(MAJOR(devt), gdev->id); + gdev->line_state_wq = alloc_ordered_workqueue(dev_name(&gdev->dev), + WQ_HIGHPRI); + if (!gdev->line_state_wq) + return -ENOMEM; + ret = cdev_device_add(&gdev->chrdev, &gdev->dev); if (ret) return ret; @@ -2765,6 +2770,7 @@ int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt) void gpiolib_cdev_unregister(struct gpio_device *gdev) { + destroy_workqueue(gdev->line_state_wq); cdev_device_del(&gdev->chrdev, &gdev->dev); blocking_notifier_call_chain(&gdev->device_notifier, 0, NULL); } diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 8daba06eb472..8737e1641278 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/notifier.h> #include <linux/srcu.h> +#include <linux/workqueue.h> #define GPIOCHIP_NAME "gpiochip" @@ -44,6 +45,8 @@ * @list: links gpio_device:s together for traversal * @line_state_notifier: used to notify subscribers about lines being * requested, released or reconfigured + * @line_state_wq: used to emit line state events from a separate thread in + * process context * @device_notifier: used to notify character device wait queues about the GPIO * device being unregistered * @srcu: protects the pointer to the underlying GPIO chip @@ -70,6 +73,7 @@ struct gpio_device { void *data; struct list_head list; struct blocking_notifier_head line_state_notifier; + struct workqueue_struct *line_state_wq; struct blocking_notifier_head device_notifier; struct srcu_struct srcu; |