]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpiolib: add a per-gpio_device line state notification workqueue
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Fri, 18 Oct 2024 09:10:13 +0000 (11:10 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Tue, 22 Oct 2024 06:59:08 +0000 (08:59 +0200)
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>
drivers/gpio/gpiolib-cdev.c
drivers/gpio/gpiolib.h

index 0cba74381687a9be081f3243f37fe3552e0f3b34..b242fdb1ad288f5f94f11fd839519a5121390baf 100644 (file)
@@ -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);
 }
index 8daba06eb472faa1ead5966aaedf16987e8aec9a..8737e164127837ba6dc0455561250750d3d6872f 100644 (file)
@@ -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;