Commit 2a9101e8 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

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: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent 1f2bcb8c
Loading
Loading
Loading
Loading
+23 −23
Original line number Diff line number Diff line
@@ -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;

	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);
+1 −1
Original line number Diff line number Diff line
@@ -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. */
+0 −1
Original line number Diff line number Diff line
@@ -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);