diff options
author | Bartosz Golaszewski <bartosz.golaszewski@linaro.org> | 2024-10-31 21:01:55 +0100 |
---|---|---|
committer | Bartosz Golaszewski <bartosz.golaszewski@linaro.org> | 2024-11-04 08:56:20 +0100 |
commit | 7b925098c937599c8ad1bc757db80743a990f57e (patch) | |
tree | bc9f9dafcafde02343a638c7c7432fedb23c71d3 /drivers/gpio | |
parent | 5a7119e0d951fdf7ebcc25a77565ac184798639a (diff) | |
download | lwn-7b925098c937599c8ad1bc757db80743a990f57e.tar.gz lwn-7b925098c937599c8ad1bc757db80743a990f57e.zip |
gpio: sysfs: emit chardev line-state events on edge store
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>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib-sysfs.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 73b1f235cf72..1acfa43bf1ab 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -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); |