gpio: don't use same lockdep class for all devm_gpiochip_add_data users
authorAhmad Fatoum <a.fatoum@pengutronix.de>
Fri, 31 Jul 2020 12:38:36 +0000 (14:38 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 3 Aug 2020 23:22:02 +0000 (01:22 +0200)
Commit 959bc7b22bd2 ("gpio: Automatically add lockdep keys") documents
in its commits message its intention to "create a unique class key for
each driver".

It does so by having gpiochip_add_data add in-place the definition of
two static lockdep classes for LOCKDEP use. That way, every caller of
the macro adds their gpiochip with unique lockdep classes.

There are many indirect callers of gpiochip_add_data, however, via
use of devm_gpiochip_add_data. devm_gpiochip_add_data has external
linkage and all its users will share the same lockdep classes, which
probably is not intended.

Fix this by replicating the gpio_chip_add_data statics-in-macro for
the devm_ version as well.

Fixes: 959bc7b22bd2 ("gpio: Automatically add lockdep keys")
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Link: https://lore.kernel.org/r/20200731123835.8003-1-a.fatoum@pengutronix.de
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib-devres.c
include/linux/gpio/driver.h

index 5c91c4365da1f92b30e48cc8c15f189caea79cdd..7dbce4c4ebdf4fe97dce05cc2631dd2fae439322 100644 (file)
@@ -487,10 +487,12 @@ static void devm_gpio_chip_release(struct device *dev, void *res)
 }
 
 /**
- * devm_gpiochip_add_data() - Resource managed gpiochip_add_data()
+ * devm_gpiochip_add_data_with_key() - Resource managed gpiochip_add_data_with_key()
  * @dev: pointer to the device that gpio_chip belongs to.
  * @gc: the GPIO chip to register
  * @data: driver-private data associated with this chip
+ * @lock_key: lockdep class for IRQ lock
+ * @request_key: lockdep class for IRQ request
  *
  * Context: potentially before irqs will work
  *
@@ -501,8 +503,9 @@ static void devm_gpio_chip_release(struct device *dev, void *res)
  * gc->base is invalid or already associated with a different chip.
  * Otherwise it returns zero as a success code.
  */
-int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *gc,
-                          void *data)
+int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc, void *data,
+                                   struct lock_class_key *lock_key,
+                                   struct lock_class_key *request_key)
 {
        struct gpio_chip **ptr;
        int ret;
@@ -512,7 +515,7 @@ int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *gc,
        if (!ptr)
                return -ENOMEM;
 
-       ret = gpiochip_add_data(gc, data);
+       ret = gpiochip_add_data_with_key(gc, data, lock_key, request_key);
        if (ret < 0) {
                devres_free(ptr);
                return ret;
@@ -523,4 +526,4 @@ int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *gc,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(devm_gpiochip_add_data);
+EXPORT_SYMBOL_GPL(devm_gpiochip_add_data_with_key);
index 6e9f1826ecd77bd3eab1be28c1e8547e7becbc9b..d1cef5c2715c0ade0d76c1aafa32d61bb3f2ea56 100644 (file)
@@ -525,8 +525,16 @@ extern int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
                gpiochip_add_data_with_key(gc, data, &lock_key, \
                                           &request_key);         \
        })
+#define devm_gpiochip_add_data(dev, gc, data) ({ \
+               static struct lock_class_key lock_key;  \
+               static struct lock_class_key request_key;         \
+               devm_gpiochip_add_data_with_key(dev, gc, data, &lock_key, \
+                                          &request_key);         \
+       })
 #else
 #define gpiochip_add_data(gc, data) gpiochip_add_data_with_key(gc, data, NULL, NULL)
+#define devm_gpiochip_add_data(dev, gc, data) \
+       devm_gpiochip_add_data_with_key(dev, gc, data, NULL, NULL)
 #endif /* CONFIG_LOCKDEP */
 
 static inline int gpiochip_add(struct gpio_chip *gc)
@@ -534,8 +542,9 @@ static inline int gpiochip_add(struct gpio_chip *gc)
        return gpiochip_add_data(gc, NULL);
 }
 extern void gpiochip_remove(struct gpio_chip *gc);
-extern int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *gc,
-                                 void *data);
+extern int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc, void *data,
+                                          struct lock_class_key *lock_key,
+                                          struct lock_class_key *request_key);
 
 extern struct gpio_chip *gpiochip_find(void *data,
                              int (*match)(struct gpio_chip *gc, void *data));