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:
parent
1f2bcb8c8c
commit
2a9101e875
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user