[PATCH v4 5/5] gpio: sysfs: emit chardev line-state events on edge store

From: Bartosz Golaszewski
Date: Thu Oct 31 2024 - 16:03:11 EST


From: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx>

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.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx>
---
drivers/gpio/gpiolib-sysfs.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 49a5aa89cafc..5d7e8e64783c 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);

--
2.45.2