[PATCH v3 21/24] gpio: add SRCU infrastructure to struct gpio_device

Bartosz Golaszewski
2024-02-08T09:59:48Z

Add the SRCU struct to GPIO device. It will be used to serialize access
to the GPIO chip pointer. Initialize and clean it up where applicable.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/gpio/gpiolib.c | 13 ++++++++++---
drivers/gpio/gpiolib.h | 2 ++
2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 6b696087c7f5..9b1907f3e400 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -680,6 +680,7 @@ static void gpiodev_release(struct device *dev)
ida_free(&gpio_ida, gdev->id);
kfree_const(gdev->label);
kfree(gdev->descs);
+ cleanup_srcu_struct(&gdev->srcu);
kfree(gdev);
}

@@ -948,6 +949,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
init_rwsem(&gdev->sem);

+ ret = init_srcu_struct(&gdev->srcu);
+ if (ret)
+ goto err_remove_from_list;
+
#ifdef CONFIG_PINCTRL
INIT_LIST_HEAD(&gdev->pin_ranges);
#endif
@@ -955,15 +960,15 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (gc->names) {
ret = gpiochip_set_desc_names(gc);
if (ret)
- goto err_remove_from_list;
+ goto err_cleanup_gdev_srcu;
}
ret = gpiochip_set_names(gc);
if (ret)
- goto err_remove_from_list;
+ goto err_cleanup_gdev_srcu;

ret = gpiochip_init_valid_mask(gc);
if (ret)
- goto err_remove_from_list;
+ goto err_cleanup_gdev_srcu;

ret = of_gpiochip_add(gc);
if (ret)
@@ -1043,6 +1048,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gpio_device_put(gdev);
goto err_print_message;
}
+err_cleanup_gdev_srcu:
+ cleanup_srcu_struct(&gdev->srcu);
err_remove_from_list:
scoped_guard(mutex, &gpio_devices_lock)
list_del_rcu(&gdev->list);
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 43ff4931e2c3..35d71e30c546 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -49,6 +49,7 @@
* @sem: protects the structure from a NULL-pointer dereference of @chip by
* user-space operations when the device gets unregistered during
* a hot-unplug event
+ * @srcu: protects the pointer to the underlying GPIO chip
* @pin_ranges: range of pins served by the GPIO driver
*
* This state container holds most of the runtime variable data
@@ -73,6 +74,7 @@ struct gpio_device {
struct blocking_notifier_head line_state_notifier;
struct blocking_notifier_head device_notifier;
struct rw_semaphore sem;
+ struct srcu_struct srcu;

#ifdef CONFIG_PINCTRL
/*
--
2.40.1