[PATCH v2 2/2] gpiolib: of: Integrate of_gpiochip_init_valid_mask() into gpiochip_init_valid_mask()

From: Andy Shevchenko
Date: Tue Nov 08 2022 - 08:38:41 EST


In preparation to complete fwnode switch, integrate
of_gpiochip_init_valid_mask() into gpiochip_init_valid_mask().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
v2: added tag (Dmitry), made sure size is validated before use (Dmitry)
drivers/gpio/gpiolib-of.c | 42 ------------------------------
drivers/gpio/gpiolib-of.h | 5 ----
drivers/gpio/gpiolib.c | 54 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 53 insertions(+), 48 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 000020eb78d8..4be3c21aa718 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -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;
diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h
index 8af2bc899aab..2c32a332ede5 100644
--- a/drivers/gpio/gpiolib-of.h
+++ b/drivers/gpio/gpiolib-of.h
@@ -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)
{
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e8faedca6b14..11fb7ec883e9 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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,
--
2.35.1