Skip to content

Commit

Permalink
gpio: sysfs: use gpio_device_find() to iterate over existing devices
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Bartosz Golaszewski committed Feb 12, 2024
1 parent 1f2bcb8 commit 2a9101e
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 25 deletions.
46 changes: 23 additions & 23 deletions drivers/gpio/gpiolib-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;

/*
* 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);
(void)gpio_device_find(NULL, gpiofind_sysfs_register);

return status;
return 0;
}
postcore_initcall(gpiolib_sysfs_init);
2 changes: 1 addition & 1 deletion drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
1 change: 0 additions & 1 deletion drivers/gpio/gpiolib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 2a9101e

Please sign in to comment.