Commit c38c3a34 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

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: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20250704-gpio-sysfs-chip-export-v4-3-9289d8758243@linaro.org


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
parent 2028f854
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -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);

		/*