lkml.org 
[lkml]   [2024]   [Feb]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 08/24] gpio: sysfs: use gpio_device_find() to iterate over existing devices
    Date
    From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

    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>
    ---
    drivers/gpio/gpiolib-sysfs.c | 46 ++++++++++++++++++------------------
    drivers/gpio/gpiolib.c | 2 +-
    drivers/gpio/gpiolib.h | 1 -
    3 files changed, 24 insertions(+), 25 deletions(-)

    diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
    index 6bf5332136e5..d6ff044ce887 100644
    --- a/drivers/gpio/gpiolib-sysfs.c
    +++ b/drivers/gpio/gpiolib-sysfs.c
    @@ -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, 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);
    diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
    index a87ab8f013c4..68543ab34fb6 100644
    --- a/drivers/gpio/gpiolib.c
    +++ b/drivers/gpio/gpiolib.c
    @@ -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. */
    diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
    index d2e73eea9e92..2bf3f9e13ae4 100644
    --- a/drivers/gpio/gpiolib.h
    +++ b/drivers/gpio/gpiolib.h
    @@ -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);

    --
    2.40.1

    \
     
     \ /
      Last update: 2024-05-27 14:54    [W:4.254 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site