]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpio: sysfs: only get the dirent reference for the value attr once
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Fri, 4 Jul 2025 12:58:50 +0000 (14:58 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Wed, 16 Jul 2025 08:27:07 +0000 (10:27 +0200)
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>
drivers/gpio/gpiolib-sysfs.c

index 990db0405cc86c42bad61295dc823f970199534e..39e9ca31f034e20abd08fb5e9b4eecf24f127d5e 100644 (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);
 
                /*