gpiolib: Add init_valid_mask exported function
authorRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Fri, 5 Oct 2018 06:52:58 +0000 (08:52 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 10 Oct 2018 08:31:40 +0000 (10:31 +0200)
Add a function that allows initializing the valid_mask from
gpiochip_add_data.

This prevents race conditions during gpiochip initialization.

If the function is not exported, then the old behaviour is respected,
this is, set all gpios as valid.

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Tested-by: Jeffrey Hugo <jhugo@codeaurora.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib.c
include/linux/gpio/driver.h

index 02660bf..b66aae7 100644 (file)
@@ -360,7 +360,7 @@ static unsigned long *gpiochip_allocate_mask(struct gpio_chip *chip)
        return p;
 }
 
-static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
+static int gpiochip_alloc_valid_mask(struct gpio_chip *gpiochip)
 {
 #ifdef CONFIG_OF_GPIO
        int size;
@@ -381,6 +381,14 @@ static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
        return 0;
 }
 
+static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
+{
+       if (gpiochip->init_valid_mask)
+               return gpiochip->init_valid_mask(gpiochip);
+
+       return 0;
+}
+
 static void gpiochip_free_valid_mask(struct gpio_chip *gpiochip)
 {
        kfree(gpiochip->valid_mask);
@@ -1369,7 +1377,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        if (status)
                goto err_remove_from_list;
 
-       status = gpiochip_init_valid_mask(chip);
+       status = gpiochip_alloc_valid_mask(chip);
        if (status)
                goto err_remove_irqchip_mask;
 
@@ -1381,6 +1389,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        if (status)
                goto err_remove_chip;
 
+       status = gpiochip_init_valid_mask(chip);
+       if (status)
+               goto err_remove_chip;
+
        acpi_gpiochip_add(chip);
 
        machine_gpiochip_add(chip);
index f6b9573..c5a51af 100644 (file)
@@ -280,6 +280,9 @@ struct gpio_chip {
 
        void                    (*dbg_show)(struct seq_file *s,
                                                struct gpio_chip *chip);
+
+       int                     (*init_valid_mask)(struct gpio_chip *chip);
+
        int                     base;
        u16                     ngpio;
        const char              *const *names;
@@ -318,7 +321,9 @@ struct gpio_chip {
        /**
         * @need_valid_mask:
         *
-        * If set core allocates @valid_mask with all bits set to one.
+        * If set core allocates @valid_mask with all its values initialized
+        * with init_valid_mask() or set to one if init_valid_mask() is not
+        * defined
         */
        bool need_valid_mask;