]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
gpio: sysfs: emit chardev line-state events on edge store
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Thu, 31 Oct 2024 20:01:55 +0000 (21:01 +0100)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Mon, 4 Nov 2024 07:56:20 +0000 (08:56 +0100)
In order to emit line-state events on edge changes in sysfs, update the
EDGE flags in the descriptor in gpio_sysfs_request_irq() and emit the
event on a successful store.

Reviewed-by: Kent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20241031-gpio-notify-sysfs-v4-5-142021c2195c@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/gpiolib-sysfs.c

index 73b1f235cf724bd785f6834abc4f71fd8d4ed625..1acfa43bf1ab02e82b1bc1cfe7f49606651e1907 100644 (file)
@@ -179,12 +179,16 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags)
                return -ENODEV;
 
        irq_flags = IRQF_SHARED;
-       if (flags & GPIO_IRQF_TRIGGER_FALLING)
+       if (flags & GPIO_IRQF_TRIGGER_FALLING) {
                irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
                        IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
-       if (flags & GPIO_IRQF_TRIGGER_RISING)
+               set_bit(FLAG_EDGE_FALLING, &desc->flags);
+       }
+       if (flags & GPIO_IRQF_TRIGGER_RISING) {
                irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
                        IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
+               set_bit(FLAG_EDGE_RISING, &desc->flags);
+       }
 
        /*
         * FIXME: This should be done in the irq_request_resources callback
@@ -210,6 +214,8 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags)
 err_unlock:
        gpiochip_unlock_as_irq(guard.gc, gpio_chip_hwgpio(desc));
 err_put_kn:
+       clear_bit(FLAG_EDGE_RISING, &desc->flags);
+       clear_bit(FLAG_EDGE_FALLING, &desc->flags);
        sysfs_put(data->value_kn);
 
        return ret;
@@ -231,6 +237,8 @@ static void gpio_sysfs_free_irq(struct device *dev)
        data->irq_flags = 0;
        free_irq(data->irq, data);
        gpiochip_unlock_as_irq(guard.gc, gpio_chip_hwgpio(desc));
+       clear_bit(FLAG_EDGE_RISING, &desc->flags);
+       clear_bit(FLAG_EDGE_FALLING, &desc->flags);
        sysfs_put(data->value_kn);
 }
 
@@ -282,6 +290,8 @@ static ssize_t edge_store(struct device *dev,
        if (status)
                return status;
 
+       gpiod_line_state_notify(data->desc, GPIO_V2_LINE_CHANGED_CONFIG);
+
        return size;
 }
 static DEVICE_ATTR_RW(edge);