From c38c3a349b7bb994252e93c7c122fa0b50ddf12b Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 4 Jul 2025 14:58:50 +0200 Subject: [PATCH] gpio: sysfs: only get the dirent reference for the value attr once There's no reason to retrieve the reference to the sysfs dirent every time we request an interrupt, we can as well only do it once when exporting the GPIO. Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20250704-gpio-sysfs-chip-export-v4-3-9289d8758243@linaro.org Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-sysfs.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 990db0405cc86..39e9ca31f034e 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -177,10 +177,6 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags) if (data->irq < 0) return -EIO; - data->value_kn = sysfs_get_dirent(dev->kobj.sd, "value"); - if (!data->value_kn) - return -ENODEV; - irq_flags = IRQF_SHARED; if (flags & GPIO_IRQF_TRIGGER_FALLING) { irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? @@ -203,7 +199,7 @@ static int gpio_sysfs_request_irq(struct device *dev, unsigned char flags) */ ret = gpiochip_lock_as_irq(guard.gc, gpio_chip_hwgpio(desc)); if (ret < 0) - goto err_put_kn; + goto err_clr_bits; ret = request_any_context_irq(data->irq, gpio_sysfs_irq, irq_flags, "gpiolib", data); @@ -216,10 +212,9 @@ 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: +err_clr_bits: clear_bit(FLAG_EDGE_RISING, &desc->flags); clear_bit(FLAG_EDGE_FALLING, &desc->flags); - sysfs_put(data->value_kn); return ret; } @@ -242,7 +237,6 @@ static void gpio_sysfs_free_irq(struct device *dev) 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); } static const char *const trigger_names[] = { @@ -726,8 +720,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) goto err_free_data; } + data->value_kn = sysfs_get_dirent(dev->kobj.sd, "value"); + if (!data->value_kn) { + status = -ENODEV; + goto err_unregister_device; + } + return 0; +err_unregister_device: + device_unregister(dev); err_free_data: kfree(data); err_clear_bit: @@ -804,6 +806,7 @@ void gpiod_unexport(struct gpio_desc *desc) data = dev_get_drvdata(dev); clear_bit(FLAG_EXPORT, &desc->flags); + sysfs_put(data->value_kn); device_unregister(dev); /* -- 2.47.2