1

gpio: sysfs: use gpio_device_find() to iterate over existing devices

With the list of GPIO devices now protected with SRCU we can use
gpio_device_find() to traverse it from sysfs.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
This commit is contained in:
Bartosz Golaszewski 2024-01-24 16:29:39 +01:00
parent 1f2bcb8c8c
commit 2a9101e875
3 changed files with 24 additions and 25 deletions

View File

@ -790,11 +790,29 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev)
}
}
/*
* We're not really looking for a device - we just want to iterate over the
* list and call this callback for each GPIO device. This is why this function
* always returns 0.
*/
static int gpiofind_sysfs_register(struct gpio_chip *gc, const void *data)
{
struct gpio_device *gdev = gc->gpiodev;
int ret;
if (gdev->mockdev)
return 0;
ret = gpiochip_sysfs_register(gdev);
if (ret)
chip_err(gc, "failed to register the sysfs entry: %d\n", ret);
return 0;
}
static int __init gpiolib_sysfs_init(void)
{
int status;
unsigned long flags;
struct gpio_device *gdev;
int status;
status = class_register(&gpio_class);
if (status < 0)
@ -806,26 +824,8 @@ static int __init gpiolib_sysfs_init(void)
* We run before arch_initcall() so chip->dev nodes can have
* registered, and so arch_initcall() can always gpiod_export().
*/
spin_lock_irqsave(&gpio_lock, flags);
list_for_each_entry(gdev, &gpio_devices, list) {
if (gdev->mockdev)
continue;
(void)gpio_device_find(NULL, gpiofind_sysfs_register);
/*
* TODO we yield gpio_lock here because
* gpiochip_sysfs_register() acquires a mutex. This is unsafe
* and needs to be fixed.
*
* Also it would be nice to use gpio_device_find() here so we
* can keep gpio_chips local to gpiolib.c, but the yield of
* gpio_lock prevents us from doing this.
*/
spin_unlock_irqrestore(&gpio_lock, flags);
status = gpiochip_sysfs_register(gdev);
spin_lock_irqsave(&gpio_lock, flags);
}
spin_unlock_irqrestore(&gpio_lock, flags);
return status;
return 0;
}
postcore_initcall(gpiolib_sysfs_init);

View File

@ -85,7 +85,7 @@ DEFINE_SPINLOCK(gpio_lock);
static DEFINE_MUTEX(gpio_lookup_lock);
static LIST_HEAD(gpio_lookup_list);
LIST_HEAD(gpio_devices);
static LIST_HEAD(gpio_devices);
/* Protects the GPIO device list against concurrent modifications. */
static DEFINE_MUTEX(gpio_devices_lock);
/* Ensures coherence during read-only accesses to the list of GPIO devices. */

View File

@ -136,7 +136,6 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
extern spinlock_t gpio_lock;
extern struct list_head gpio_devices;
void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action);