gpiolib: of: Integrate of_gpiochip_init_valid_mask() into gpiochip_init_valid_mask()
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 8 Nov 2022 13:38:53 +0000 (15:38 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Wed, 9 Nov 2022 13:10:27 +0000 (14:10 +0100)
In preparation to complete fwnode switch, integrate
of_gpiochip_init_valid_mask() into gpiochip_init_valid_mask().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib-of.h
drivers/gpio/gpiolib.c

index 000020eb78d83cb562228211c9363b0f81673577..4be3c21aa71883deb8518f1284ad0c20712064c3 100644 (file)
@@ -112,24 +112,6 @@ static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip,
        return gpiochip_get_desc(chip, ret);
 }
 
-/**
- * of_gpio_need_valid_mask() - figure out if the OF GPIO driver needs
- * to set the .valid_mask
- * @gc: the target gpio_chip
- *
- * Return: true if the valid mask needs to be set
- */
-bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
-{
-       int size;
-       const struct device_node *np = gc->of_node;
-
-       size = of_property_count_u32_elems(np,  "gpio-reserved-ranges");
-       if (size > 0 && size % 2 == 0)
-               return true;
-       return false;
-}
-
 /*
  * Overrides stated polarity of a gpio line and warns when there is a
  * discrepancy.
@@ -989,28 +971,6 @@ void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc)
 }
 EXPORT_SYMBOL_GPL(of_mm_gpiochip_remove);
 
-static void of_gpiochip_init_valid_mask(struct gpio_chip *chip)
-{
-       int len, i;
-       u32 start, count;
-       struct device_node *np = chip->of_node;
-
-       len = of_property_count_u32_elems(np,  "gpio-reserved-ranges");
-       if (len < 0 || len % 2 != 0)
-               return;
-
-       for (i = 0; i < len; i += 2) {
-               of_property_read_u32_index(np, "gpio-reserved-ranges",
-                                          i, &start);
-               of_property_read_u32_index(np, "gpio-reserved-ranges",
-                                          i + 1, &count);
-               if (start >= chip->ngpio || start + count > chip->ngpio)
-                       continue;
-
-               bitmap_clear(chip->valid_mask, start, count);
-       }
-};
-
 #ifdef CONFIG_PINCTRL
 static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
 {
@@ -1119,8 +1079,6 @@ int of_gpiochip_add(struct gpio_chip *chip)
        if (chip->of_gpio_n_cells > MAX_PHANDLE_ARGS)
                return -EINVAL;
 
-       of_gpiochip_init_valid_mask(chip);
-
        ret = of_gpiochip_add_pin_range(chip);
        if (ret)
                return ret;
index 8af2bc899aab251082f11441beb1618183a4b1d4..2c32a332ede595d6f79ec373e865aef926613745 100644 (file)
@@ -14,7 +14,6 @@ struct gpio_desc *of_find_gpio(struct device *dev,
 int of_gpiochip_add(struct gpio_chip *gc);
 void of_gpiochip_remove(struct gpio_chip *gc);
 int of_gpio_get_count(struct device *dev, const char *con_id);
-bool of_gpio_need_valid_mask(const struct gpio_chip *gc);
 void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev);
 #else
 static inline struct gpio_desc *of_find_gpio(struct device *dev,
@@ -30,10 +29,6 @@ static inline int of_gpio_get_count(struct device *dev, const char *con_id)
 {
        return 0;
 }
-static inline bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
-{
-       return false;
-}
 static inline void of_gpio_dev_init(struct gpio_chip *gc,
                                    struct gpio_device *gdev)
 {
index e8faedca6b14f15c543c5be8961ab4e697b8ebe3..11fb7ec883e9f61700a151b4d224fc27ebe826e4 100644 (file)
@@ -445,9 +445,21 @@ static unsigned long *gpiochip_allocate_mask(struct gpio_chip *gc)
        return p;
 }
 
+static unsigned int gpiochip_count_reserved_ranges(struct gpio_chip *gc)
+{
+       int size;
+
+       /* Format is "start, count, ..." */
+       size = fwnode_property_count_u32(gc->fwnode, "gpio-reserved-ranges");
+       if (size > 0 && size % 2 == 0)
+               return size;
+
+       return 0;
+}
+
 static int gpiochip_alloc_valid_mask(struct gpio_chip *gc)
 {
-       if (!(of_gpio_need_valid_mask(gc) || gc->init_valid_mask))
+       if (!(gpiochip_count_reserved_ranges(gc) || gc->init_valid_mask))
                return 0;
 
        gc->valid_mask = gpiochip_allocate_mask(gc);
@@ -457,8 +469,48 @@ static int gpiochip_alloc_valid_mask(struct gpio_chip *gc)
        return 0;
 }
 
+static int gpiochip_apply_reserved_ranges(struct gpio_chip *gc)
+{
+       unsigned int size;
+       u32 *ranges;
+       int ret;
+
+       size = gpiochip_count_reserved_ranges(gc);
+       if (size == 0)
+               return 0;
+
+       ranges = kmalloc_array(size, sizeof(*ranges), GFP_KERNEL);
+       if (!ranges)
+               return -ENOMEM;
+
+       ret = fwnode_property_read_u32_array(gc->fwnode, "gpio-reserved-ranges", ranges, size);
+       if (ret) {
+               kfree(ranges);
+               return ret;
+       }
+
+       while (size) {
+               u32 count = ranges[--size];
+               u32 start = ranges[--size];
+
+               if (start >= gc->ngpio || start + count > gc->ngpio)
+                       continue;
+
+               bitmap_clear(gc->valid_mask, start, count);
+       }
+
+       kfree(ranges);
+       return 0;
+}
+
 static int gpiochip_init_valid_mask(struct gpio_chip *gc)
 {
+       int ret;
+
+       ret = gpiochip_apply_reserved_ranges(gc);
+       if (ret)
+               return ret;
+
        if (gc->init_valid_mask)
                return gc->init_valid_mask(gc,
                                           gc->valid_mask,