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 <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20250704-gpio-sysfs-chip-export-v4-3-9289d8758243@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
Bartosz Golaszewski 2025-07-04 14:58:50 +02:00
parent 2028f854b3
commit c38c3a349b

View file

@ -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);
/*