From 1f56f0e5f228c78549ec2ebc07b63ba0e10ee8e0 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 22 Jan 2024 05:34:59 -0500 Subject: [PATCH] Drop gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch Signed-off-by: Sasha Levin --- ...tex-to-protect-the-list-of-gpio-devi.patch | 400 ------------------ queue-6.6/series | 1 - ...tex-to-protect-the-list-of-gpio-devi.patch | 400 ------------------ queue-6.7/series | 1 - 4 files changed, 802 deletions(-) delete mode 100644 queue-6.6/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch delete mode 100644 queue-6.7/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch diff --git a/queue-6.6/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch b/queue-6.6/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch deleted file mode 100644 index db6342ad999..00000000000 --- a/queue-6.6/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch +++ /dev/null @@ -1,400 +0,0 @@ -From 962616d67e96d400fca23f3ab8be6865608f39b1 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 15 Dec 2023 16:53:00 +0100 -Subject: gpiolib: use a mutex to protect the list of GPIO devices - -From: Bartosz Golaszewski - -[ Upstream commit 65a828bab15887b33336d251fd659b2ae86de6d6 ] - -The global list of GPIO devices is never modified or accessed from -atomic context so it's fine to protect it using a mutex. Add a new -global lock dedicated to the gpio_devices list and use it whenever -accessing or modifying it. - -Signed-off-by: Bartosz Golaszewski -Reviewed-by: Andy Shevchenko -Stable-dep-of: 48e1b4d369cf ("gpiolib: remove the GPIO device from the list when it's unregistered") -Signed-off-by: Sasha Levin ---- - drivers/gpio/gpiolib-sysfs.c | 45 ++++++------ - drivers/gpio/gpiolib-sysfs.h | 6 ++ - drivers/gpio/gpiolib.c | 137 ++++++++++++++++------------------- - drivers/gpio/gpiolib.h | 2 + - 4 files changed, 90 insertions(+), 100 deletions(-) - -diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c -index 12d853845bb8..1e91e7395d01 100644 ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -769,6 +769,25 @@ int gpiochip_sysfs_register(struct gpio_device *gdev) - return 0; - } - -+int gpiochip_sysfs_register_all(void) -+{ -+ struct gpio_device *gdev; -+ int ret; -+ -+ guard(mutex)(&gpio_devices_lock); -+ -+ list_for_each_entry(gdev, &gpio_devices, list) { -+ if (gdev->mockdev) -+ continue; -+ -+ ret = gpiochip_sysfs_register(gdev); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - void gpiochip_sysfs_unregister(struct gpio_device *gdev) - { - struct gpio_desc *desc; -@@ -793,9 +812,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) - - 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) -@@ -807,26 +824,6 @@ 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); -- -- return status; -+ return gpiochip_sysfs_register_all(); - } - postcore_initcall(gpiolib_sysfs_init); -diff --git a/drivers/gpio/gpiolib-sysfs.h b/drivers/gpio/gpiolib-sysfs.h -index b794b396d6a5..ab157cec0b4b 100644 ---- a/drivers/gpio/gpiolib-sysfs.h -+++ b/drivers/gpio/gpiolib-sysfs.h -@@ -8,6 +8,7 @@ struct gpio_device; - #ifdef CONFIG_GPIO_SYSFS - - int gpiochip_sysfs_register(struct gpio_device *gdev); -+int gpiochip_sysfs_register_all(void); - void gpiochip_sysfs_unregister(struct gpio_device *gdev); - - #else -@@ -17,6 +18,11 @@ static inline int gpiochip_sysfs_register(struct gpio_device *gdev) - return 0; - } - -+static inline int gpiochip_sysfs_register_all(void) -+{ -+ return 0; -+} -+ - static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev) - { - } -diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c -index d722b6301906..1a53e1e5379b 100644 ---- a/drivers/gpio/gpiolib.c -+++ b/drivers/gpio/gpiolib.c -@@ -2,6 +2,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -15,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -93,7 +95,9 @@ DEFINE_SPINLOCK(gpio_lock); - - static DEFINE_MUTEX(gpio_lookup_lock); - static LIST_HEAD(gpio_lookup_list); -+ - LIST_HEAD(gpio_devices); -+DEFINE_MUTEX(gpio_devices_lock); - - static DEFINE_MUTEX(gpio_machine_hogs_mutex); - static LIST_HEAD(gpio_machine_hogs); -@@ -125,20 +129,15 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) - struct gpio_desc *gpio_to_desc(unsigned gpio) - { - struct gpio_device *gdev; -- unsigned long flags; -- -- spin_lock_irqsave(&gpio_lock, flags); - -- list_for_each_entry(gdev, &gpio_devices, list) { -- if (gdev->base <= gpio && -- gdev->base + gdev->ngpio > gpio) { -- spin_unlock_irqrestore(&gpio_lock, flags); -- return &gdev->descs[gpio - gdev->base]; -+ scoped_guard(mutex, &gpio_devices_lock) { -+ list_for_each_entry(gdev, &gpio_devices, list) { -+ if (gdev->base <= gpio && -+ gdev->base + gdev->ngpio > gpio) -+ return &gdev->descs[gpio - gdev->base]; - } - } - -- spin_unlock_irqrestore(&gpio_lock, flags); -- - if (!gpio_is_valid(gpio)) - pr_warn("invalid GPIO %d\n", gpio); - -@@ -320,26 +319,21 @@ static int gpiodev_add_to_list_unlocked(struct gpio_device *gdev) - static struct gpio_desc *gpio_name_to_desc(const char * const name) - { - struct gpio_device *gdev; -- unsigned long flags; - - if (!name) - return NULL; - -- spin_lock_irqsave(&gpio_lock, flags); -+ guard(mutex)(&gpio_devices_lock); - - list_for_each_entry(gdev, &gpio_devices, list) { - struct gpio_desc *desc; - - for_each_gpio_desc(gdev->chip, desc) { -- if (desc->name && !strcmp(desc->name, name)) { -- spin_unlock_irqrestore(&gpio_lock, flags); -+ if (desc->name && !strcmp(desc->name, name)) - return desc; -- } - } - } - -- spin_unlock_irqrestore(&gpio_lock, flags); -- - return NULL; - } - -@@ -577,11 +571,9 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid); - static void gpiodev_release(struct device *dev) - { - struct gpio_device *gdev = to_gpio_device(dev); -- unsigned long flags; - -- spin_lock_irqsave(&gpio_lock, flags); -- list_del(&gdev->list); -- spin_unlock_irqrestore(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) -+ list_del(&gdev->list); - - ida_free(&gpio_ida, gdev->id); - kfree_const(gdev->label); -@@ -739,7 +731,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - struct lock_class_key *request_key) - { - struct gpio_device *gdev; -- unsigned long flags; - unsigned int i; - int base = 0; - int ret = 0; -@@ -804,49 +795,46 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - - gdev->ngpio = gc->ngpio; - -- spin_lock_irqsave(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) { -+ /* -+ * TODO: this allocates a Linux GPIO number base in the global -+ * GPIO numberspace for this chip. In the long run we want to -+ * get *rid* of this numberspace and use only descriptors, but -+ * it may be a pipe dream. It will not happen before we get rid -+ * of the sysfs interface anyways. -+ */ -+ base = gc->base; - -- /* -- * TODO: this allocates a Linux GPIO number base in the global -- * GPIO numberspace for this chip. In the long run we want to -- * get *rid* of this numberspace and use only descriptors, but -- * it may be a pipe dream. It will not happen before we get rid -- * of the sysfs interface anyways. -- */ -- base = gc->base; -- if (base < 0) { -- base = gpiochip_find_base_unlocked(gc->ngpio); - if (base < 0) { -- spin_unlock_irqrestore(&gpio_lock, flags); -- ret = base; -- base = 0; -+ base = gpiochip_find_base_unlocked(gc->ngpio); -+ if (base < 0) { -+ ret = base; -+ base = 0; -+ goto err_free_label; -+ } -+ /* -+ * TODO: it should not be necessary to reflect the assigned -+ * base outside of the GPIO subsystem. Go over drivers and -+ * see if anyone makes use of this, else drop this and assign -+ * a poison instead. -+ */ -+ gc->base = base; -+ } else { -+ dev_warn(&gdev->dev, -+ "Static allocation of GPIO base is deprecated, use dynamic allocation.\n"); -+ } -+ gdev->base = base; -+ -+ ret = gpiodev_add_to_list_unlocked(gdev); -+ if (ret) { -+ chip_err(gc, "GPIO integer space overlap, cannot add chip\n"); - goto err_free_label; - } -- /* -- * TODO: it should not be necessary to reflect the assigned -- * base outside of the GPIO subsystem. Go over drivers and -- * see if anyone makes use of this, else drop this and assign -- * a poison instead. -- */ -- gc->base = base; -- } else { -- dev_warn(&gdev->dev, -- "Static allocation of GPIO base is deprecated, use dynamic allocation.\n"); -- } -- gdev->base = base; - -- ret = gpiodev_add_to_list_unlocked(gdev); -- if (ret) { -- spin_unlock_irqrestore(&gpio_lock, flags); -- chip_err(gc, "GPIO integer space overlap, cannot add chip\n"); -- goto err_free_label; -+ for (i = 0; i < gc->ngpio; i++) -+ gdev->descs[i].gdev = gdev; - } - -- for (i = 0; i < gc->ngpio; i++) -- gdev->descs[i].gdev = gdev; -- -- spin_unlock_irqrestore(&gpio_lock, flags); -- - BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier); - BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier); - init_rwsem(&gdev->sem); -@@ -937,9 +925,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - goto err_print_message; - } - err_remove_from_list: -- spin_lock_irqsave(&gpio_lock, flags); -- list_del(&gdev->list); -- spin_unlock_irqrestore(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) -+ list_del(&gdev->list); - err_free_label: - kfree_const(gdev->label); - err_free_descs: -@@ -1070,7 +1057,7 @@ struct gpio_device *gpio_device_find(void *data, - */ - might_sleep(); - -- guard(spinlock_irqsave)(&gpio_lock); -+ guard(mutex)(&gpio_devices_lock); - - list_for_each_entry(gdev, &gpio_devices, list) { - if (gdev->chip && match(gdev->chip, data)) -@@ -4626,35 +4613,33 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) - - static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) - { -- unsigned long flags; - struct gpio_device *gdev = NULL; - loff_t index = *pos; - - s->private = ""; - -- spin_lock_irqsave(&gpio_lock, flags); -- list_for_each_entry(gdev, &gpio_devices, list) -- if (index-- == 0) { -- spin_unlock_irqrestore(&gpio_lock, flags); -+ guard(mutex)(&gpio_devices_lock); -+ -+ list_for_each_entry(gdev, &gpio_devices, list) { -+ if (index-- == 0) - return gdev; -- } -- spin_unlock_irqrestore(&gpio_lock, flags); -+ } - - return NULL; - } - - static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) - { -- unsigned long flags; - struct gpio_device *gdev = v; - void *ret = NULL; - -- spin_lock_irqsave(&gpio_lock, flags); -- if (list_is_last(&gdev->list, &gpio_devices)) -- ret = NULL; -- else -- ret = list_first_entry(&gdev->list, struct gpio_device, list); -- spin_unlock_irqrestore(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) { -+ if (list_is_last(&gdev->list, &gpio_devices)) -+ ret = NULL; -+ else -+ ret = list_first_entry(&gdev->list, struct gpio_device, -+ list); -+ } - - s->private = "\n"; - ++*pos; -diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h -index aa1926083689..3e0f01d5d4cb 100644 ---- a/drivers/gpio/gpiolib.h -+++ b/drivers/gpio/gpiolib.h -@@ -15,6 +15,7 @@ - #include /* for enum gpiod_flags */ - #include - #include -+#include - #include - #include - -@@ -136,6 +137,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, - - extern spinlock_t gpio_lock; - extern struct list_head gpio_devices; -+extern struct mutex gpio_devices_lock; - - void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action); - --- -2.43.0 - diff --git a/queue-6.6/series b/queue-6.6/series index 486ea16b5f6..9c6bb518d4b 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -329,7 +329,6 @@ gpiolib-make-gpio_device_get-and-gpio_device_put-pub.patch gpiolib-provide-gpio_device_find.patch gpio-sysfs-drop-the-mention-of-gpiochip_find-from-sy.patch gpiolib-rename-static-functions-that-are-called-with.patch -gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch gpiolib-remove-the-gpio-device-from-the-list-when-it.patch ib-iser-prevent-invalidating-wrong-mr.patch drm-amdkfd-confirm-list-is-non-empty-before-utilizin.patch diff --git a/queue-6.7/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch b/queue-6.7/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch deleted file mode 100644 index 85870d23543..00000000000 --- a/queue-6.7/gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch +++ /dev/null @@ -1,400 +0,0 @@ -From da7a9adaae4424fca4134f6089a4490e431a4b35 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 15 Dec 2023 16:53:00 +0100 -Subject: gpiolib: use a mutex to protect the list of GPIO devices - -From: Bartosz Golaszewski - -[ Upstream commit 65a828bab15887b33336d251fd659b2ae86de6d6 ] - -The global list of GPIO devices is never modified or accessed from -atomic context so it's fine to protect it using a mutex. Add a new -global lock dedicated to the gpio_devices list and use it whenever -accessing or modifying it. - -Signed-off-by: Bartosz Golaszewski -Reviewed-by: Andy Shevchenko -Stable-dep-of: 48e1b4d369cf ("gpiolib: remove the GPIO device from the list when it's unregistered") -Signed-off-by: Sasha Levin ---- - drivers/gpio/gpiolib-sysfs.c | 45 ++++++------ - drivers/gpio/gpiolib-sysfs.h | 6 ++ - drivers/gpio/gpiolib.c | 137 ++++++++++++++++------------------- - drivers/gpio/gpiolib.h | 2 + - 4 files changed, 90 insertions(+), 100 deletions(-) - -diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c -index 12d853845bb8..1e91e7395d01 100644 ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -769,6 +769,25 @@ int gpiochip_sysfs_register(struct gpio_device *gdev) - return 0; - } - -+int gpiochip_sysfs_register_all(void) -+{ -+ struct gpio_device *gdev; -+ int ret; -+ -+ guard(mutex)(&gpio_devices_lock); -+ -+ list_for_each_entry(gdev, &gpio_devices, list) { -+ if (gdev->mockdev) -+ continue; -+ -+ ret = gpiochip_sysfs_register(gdev); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - void gpiochip_sysfs_unregister(struct gpio_device *gdev) - { - struct gpio_desc *desc; -@@ -793,9 +812,7 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) - - 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) -@@ -807,26 +824,6 @@ 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); -- -- return status; -+ return gpiochip_sysfs_register_all(); - } - postcore_initcall(gpiolib_sysfs_init); -diff --git a/drivers/gpio/gpiolib-sysfs.h b/drivers/gpio/gpiolib-sysfs.h -index b794b396d6a5..ab157cec0b4b 100644 ---- a/drivers/gpio/gpiolib-sysfs.h -+++ b/drivers/gpio/gpiolib-sysfs.h -@@ -8,6 +8,7 @@ struct gpio_device; - #ifdef CONFIG_GPIO_SYSFS - - int gpiochip_sysfs_register(struct gpio_device *gdev); -+int gpiochip_sysfs_register_all(void); - void gpiochip_sysfs_unregister(struct gpio_device *gdev); - - #else -@@ -17,6 +18,11 @@ static inline int gpiochip_sysfs_register(struct gpio_device *gdev) - return 0; - } - -+static inline int gpiochip_sysfs_register_all(void) -+{ -+ return 0; -+} -+ - static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev) - { - } -diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c -index 9e69d42ff5af..3518481c433f 100644 ---- a/drivers/gpio/gpiolib.c -+++ b/drivers/gpio/gpiolib.c -@@ -2,6 +2,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -15,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -94,7 +96,9 @@ DEFINE_SPINLOCK(gpio_lock); - - static DEFINE_MUTEX(gpio_lookup_lock); - static LIST_HEAD(gpio_lookup_list); -+ - LIST_HEAD(gpio_devices); -+DEFINE_MUTEX(gpio_devices_lock); - - static DEFINE_MUTEX(gpio_machine_hogs_mutex); - static LIST_HEAD(gpio_machine_hogs); -@@ -126,20 +130,15 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) - struct gpio_desc *gpio_to_desc(unsigned gpio) - { - struct gpio_device *gdev; -- unsigned long flags; -- -- spin_lock_irqsave(&gpio_lock, flags); - -- list_for_each_entry(gdev, &gpio_devices, list) { -- if (gdev->base <= gpio && -- gdev->base + gdev->ngpio > gpio) { -- spin_unlock_irqrestore(&gpio_lock, flags); -- return &gdev->descs[gpio - gdev->base]; -+ scoped_guard(mutex, &gpio_devices_lock) { -+ list_for_each_entry(gdev, &gpio_devices, list) { -+ if (gdev->base <= gpio && -+ gdev->base + gdev->ngpio > gpio) -+ return &gdev->descs[gpio - gdev->base]; - } - } - -- spin_unlock_irqrestore(&gpio_lock, flags); -- - if (!gpio_is_valid(gpio)) - pr_warn("invalid GPIO %d\n", gpio); - -@@ -398,26 +397,21 @@ static int gpiodev_add_to_list_unlocked(struct gpio_device *gdev) - static struct gpio_desc *gpio_name_to_desc(const char * const name) - { - struct gpio_device *gdev; -- unsigned long flags; - - if (!name) - return NULL; - -- spin_lock_irqsave(&gpio_lock, flags); -+ guard(mutex)(&gpio_devices_lock); - - list_for_each_entry(gdev, &gpio_devices, list) { - struct gpio_desc *desc; - - for_each_gpio_desc(gdev->chip, desc) { -- if (desc->name && !strcmp(desc->name, name)) { -- spin_unlock_irqrestore(&gpio_lock, flags); -+ if (desc->name && !strcmp(desc->name, name)) - return desc; -- } - } - } - -- spin_unlock_irqrestore(&gpio_lock, flags); -- - return NULL; - } - -@@ -655,11 +649,9 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid); - static void gpiodev_release(struct device *dev) - { - struct gpio_device *gdev = to_gpio_device(dev); -- unsigned long flags; - -- spin_lock_irqsave(&gpio_lock, flags); -- list_del(&gdev->list); -- spin_unlock_irqrestore(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) -+ list_del(&gdev->list); - - ida_free(&gpio_ida, gdev->id); - kfree_const(gdev->label); -@@ -817,7 +809,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - struct lock_class_key *request_key) - { - struct gpio_device *gdev; -- unsigned long flags; - unsigned int i; - int base = 0; - int ret = 0; -@@ -882,49 +873,46 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - - gdev->ngpio = gc->ngpio; - -- spin_lock_irqsave(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) { -+ /* -+ * TODO: this allocates a Linux GPIO number base in the global -+ * GPIO numberspace for this chip. In the long run we want to -+ * get *rid* of this numberspace and use only descriptors, but -+ * it may be a pipe dream. It will not happen before we get rid -+ * of the sysfs interface anyways. -+ */ -+ base = gc->base; - -- /* -- * TODO: this allocates a Linux GPIO number base in the global -- * GPIO numberspace for this chip. In the long run we want to -- * get *rid* of this numberspace and use only descriptors, but -- * it may be a pipe dream. It will not happen before we get rid -- * of the sysfs interface anyways. -- */ -- base = gc->base; -- if (base < 0) { -- base = gpiochip_find_base_unlocked(gc->ngpio); - if (base < 0) { -- spin_unlock_irqrestore(&gpio_lock, flags); -- ret = base; -- base = 0; -+ base = gpiochip_find_base_unlocked(gc->ngpio); -+ if (base < 0) { -+ ret = base; -+ base = 0; -+ goto err_free_label; -+ } -+ /* -+ * TODO: it should not be necessary to reflect the assigned -+ * base outside of the GPIO subsystem. Go over drivers and -+ * see if anyone makes use of this, else drop this and assign -+ * a poison instead. -+ */ -+ gc->base = base; -+ } else { -+ dev_warn(&gdev->dev, -+ "Static allocation of GPIO base is deprecated, use dynamic allocation.\n"); -+ } -+ gdev->base = base; -+ -+ ret = gpiodev_add_to_list_unlocked(gdev); -+ if (ret) { -+ chip_err(gc, "GPIO integer space overlap, cannot add chip\n"); - goto err_free_label; - } -- /* -- * TODO: it should not be necessary to reflect the assigned -- * base outside of the GPIO subsystem. Go over drivers and -- * see if anyone makes use of this, else drop this and assign -- * a poison instead. -- */ -- gc->base = base; -- } else { -- dev_warn(&gdev->dev, -- "Static allocation of GPIO base is deprecated, use dynamic allocation.\n"); -- } -- gdev->base = base; - -- ret = gpiodev_add_to_list_unlocked(gdev); -- if (ret) { -- spin_unlock_irqrestore(&gpio_lock, flags); -- chip_err(gc, "GPIO integer space overlap, cannot add chip\n"); -- goto err_free_label; -+ for (i = 0; i < gc->ngpio; i++) -+ gdev->descs[i].gdev = gdev; - } - -- for (i = 0; i < gc->ngpio; i++) -- gdev->descs[i].gdev = gdev; -- -- spin_unlock_irqrestore(&gpio_lock, flags); -- - BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier); - BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier); - init_rwsem(&gdev->sem); -@@ -1015,9 +1003,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, - goto err_print_message; - } - err_remove_from_list: -- spin_lock_irqsave(&gpio_lock, flags); -- list_del(&gdev->list); -- spin_unlock_irqrestore(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) -+ list_del(&gdev->list); - err_free_label: - kfree_const(gdev->label); - err_free_descs: -@@ -1126,7 +1113,7 @@ struct gpio_device *gpio_device_find(void *data, - */ - might_sleep(); - -- guard(spinlock_irqsave)(&gpio_lock); -+ guard(mutex)(&gpio_devices_lock); - - list_for_each_entry(gdev, &gpio_devices, list) { - if (gdev->chip && match(gdev->chip, data)) -@@ -4727,35 +4714,33 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) - - static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) - { -- unsigned long flags; - struct gpio_device *gdev = NULL; - loff_t index = *pos; - - s->private = ""; - -- spin_lock_irqsave(&gpio_lock, flags); -- list_for_each_entry(gdev, &gpio_devices, list) -- if (index-- == 0) { -- spin_unlock_irqrestore(&gpio_lock, flags); -+ guard(mutex)(&gpio_devices_lock); -+ -+ list_for_each_entry(gdev, &gpio_devices, list) { -+ if (index-- == 0) - return gdev; -- } -- spin_unlock_irqrestore(&gpio_lock, flags); -+ } - - return NULL; - } - - static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos) - { -- unsigned long flags; - struct gpio_device *gdev = v; - void *ret = NULL; - -- spin_lock_irqsave(&gpio_lock, flags); -- if (list_is_last(&gdev->list, &gpio_devices)) -- ret = NULL; -- else -- ret = list_first_entry(&gdev->list, struct gpio_device, list); -- spin_unlock_irqrestore(&gpio_lock, flags); -+ scoped_guard(mutex, &gpio_devices_lock) { -+ if (list_is_last(&gdev->list, &gpio_devices)) -+ ret = NULL; -+ else -+ ret = list_first_entry(&gdev->list, struct gpio_device, -+ list); -+ } - - s->private = "\n"; - ++*pos; -diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h -index 3ccacf3c1288..8142b5cbc395 100644 ---- a/drivers/gpio/gpiolib.h -+++ b/drivers/gpio/gpiolib.h -@@ -15,6 +15,7 @@ - #include /* for enum gpiod_flags */ - #include - #include -+#include - #include - #include - -@@ -136,6 +137,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory); - - extern spinlock_t gpio_lock; - extern struct list_head gpio_devices; -+extern struct mutex gpio_devices_lock; - - void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action); - --- -2.43.0 - diff --git a/queue-6.7/series b/queue-6.7/series index 479e91f2173..a34a87036f4 100644 --- a/queue-6.7/series +++ b/queue-6.7/series @@ -365,7 +365,6 @@ mmc-sdhci_am654-fix-ti-soc-dependencies.patch mmc-sdhci_omap-fix-ti-soc-dependencies.patch drm-amdkfd-fix-type-of-dbg_flags-in-struct-kfd_proce.patch gpiolib-rename-static-functions-that-are-called-with.patch -gpiolib-use-a-mutex-to-protect-the-list-of-gpio-devi.patch gpiolib-remove-the-gpio-device-from-the-list-when-it.patch ib-iser-prevent-invalidating-wrong-mr.patch drm-amdkfd-confirm-list-is-non-empty-before-utilizin.patch -- 2.47.3