Commit 7b925098 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

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: default avatarKent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20241031-gpio-notify-sysfs-v4-5-142021c2195c@linaro.org


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
parent 5a7119e0
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -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);