Tease apart of_find_gpio() into common function that works on the
firmware node, and a fallback handler that works on the device
structure, so that we can later use of_find_gpio() in
fwnode_gpiod_get_index().

Signed-off-by: Dmitry Torokhov <[email protected]>
---

 drivers/gpio/gpiolib-of.c | 149 +++++++++++++++++++-------------------
 drivers/gpio/gpiolib-of.h |  26 +++++--
 drivers/gpio/gpiolib.c    |   7 +-
 3 files changed, 99 insertions(+), 83 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 8b773f7d7724..1d1a18e0ad93 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -276,6 +276,28 @@ int of_get_named_gpio_flags(struct device_node *np, const 
char *list_name,
 }
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
+static void of_gpio_flags_to_lookup(enum of_gpio_flags of_flags,
+                                   unsigned long *flags)
+{
+       if (of_flags & OF_GPIO_ACTIVE_LOW)
+               *flags |= GPIO_ACTIVE_LOW;
+
+       if (of_flags & OF_GPIO_SINGLE_ENDED) {
+               if (of_flags & OF_GPIO_OPEN_DRAIN)
+                       *flags |= GPIO_OPEN_DRAIN;
+               else
+                       *flags |= GPIO_OPEN_SOURCE;
+       }
+
+       if (of_flags & OF_GPIO_TRANSITORY)
+               *flags |= GPIO_TRANSITORY;
+
+       if (of_flags & OF_GPIO_PULL_UP)
+               *flags |= GPIO_PULL_UP;
+       if (of_flags & OF_GPIO_PULL_DOWN)
+               *flags |= GPIO_PULL_DOWN;
+}
+
 /**
  * gpiod_get_from_of_node() - obtain a GPIO from an OF node
  * @node:      handle of the OF node
@@ -298,10 +320,6 @@ struct gpio_desc *gpiod_get_from_of_node(struct 
device_node *node,
        unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc;
        enum of_gpio_flags flags;
-       bool active_low = false;
-       bool single_ended = false;
-       bool open_drain = false;
-       bool transitory = false;
        int ret;
 
        desc = of_get_named_gpiod_flags(node, propname,
@@ -311,29 +329,13 @@ struct gpio_desc *gpiod_get_from_of_node(struct 
device_node *node,
                return desc;
        }
 
-       active_low = flags & OF_GPIO_ACTIVE_LOW;
-       single_ended = flags & OF_GPIO_SINGLE_ENDED;
-       open_drain = flags & OF_GPIO_OPEN_DRAIN;
-       transitory = flags & OF_GPIO_TRANSITORY;
-
        ret = gpiod_request(desc, label);
        if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
                return desc;
        if (ret)
                return ERR_PTR(ret);
 
-       if (active_low)
-               lflags |= GPIO_ACTIVE_LOW;
-
-       if (single_ended) {
-               if (open_drain)
-                       lflags |= GPIO_OPEN_DRAIN;
-               else
-                       lflags |= GPIO_OPEN_SOURCE;
-       }
-
-       if (transitory)
-               lflags |= GPIO_TRANSITORY;
+       of_gpio_flags_to_lookup(flags, &lflags);
 
        ret = gpiod_configure_flags(desc, propname, lflags, dflags);
        if (ret < 0) {
@@ -345,6 +347,46 @@ struct gpio_desc *gpiod_get_from_of_node(struct 
device_node *node,
 }
 EXPORT_SYMBOL(gpiod_get_from_of_node);
 
+static struct gpio_desc *of_find_node_gpio(struct device_node *np,
+                                          const char *con_id, unsigned int idx,
+                                          enum of_gpio_flags *of_flags)
+{
+       struct gpio_desc *desc;
+       char prop_name[32]; /* 32 is max size of property name */
+       unsigned int i;
+
+       /* Try GPIO property "foo-gpios" and "foo-gpio" */
+       for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
+               if (con_id)
+                       snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id,
+                                gpio_suffixes[i]);
+               else
+                       snprintf(prop_name, sizeof(prop_name), "%s",
+                                gpio_suffixes[i]);
+
+               desc = of_get_named_gpiod_flags(np, prop_name, idx, of_flags);
+               if (!IS_ERR(desc) || PTR_ERR(desc) != -ENOENT)
+                       break;
+       }
+
+       return desc;
+}
+
+struct gpio_desc *of_find_gpio(struct fwnode_handle *fwnode,
+                              const char *con_id, unsigned int idx,
+                              unsigned long *flags)
+{
+       struct device_node *np = to_of_node(fwnode);
+       struct gpio_desc *desc;
+       enum of_gpio_flags of_flags;
+
+       desc = of_find_node_gpio(np, con_id, idx, &of_flags);
+       if (!IS_ERR(desc))
+               of_gpio_flags_to_lookup(of_flags, flags);
+
+       return desc;
+}
+
 /*
  * The SPI GPIO bindings happened before we managed to establish that GPIO
  * properties should be named "foo-gpios" so we have this special kludge for
@@ -383,7 +425,7 @@ static struct gpio_desc *of_find_spi_gpio(struct device 
*dev, const char *con_id
 static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev,
                                             const char *con_id,
                                             unsigned int idx,
-                                            unsigned long *flags)
+                                            enum of_gpio_flags *of_flags)
 {
        struct device_node *np = dev->of_node;
 
@@ -403,7 +445,7 @@ static struct gpio_desc *of_find_spi_cs_gpio(struct device 
*dev,
         * uses just "gpios" so translate to that when "cs-gpios" is
         * requested.
         */
-       return of_find_gpio(dev, NULL, idx, flags);
+       return of_find_node_gpio(dev->of_node, NULL, idx, of_flags);
 }
 
 /*
@@ -451,41 +493,18 @@ static struct gpio_desc *of_find_arizona_gpio(struct 
device *dev,
        return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags);
 }
 
-struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
-                              unsigned int idx, unsigned long *flags)
+struct gpio_desc *of_find_gpio_fallback(struct device *dev,
+                                       const char *con_id, unsigned int idx,
+                                       unsigned long *flags)
 {
-       char prop_name[32]; /* 32 is max size of property name */
-       enum of_gpio_flags of_flags;
        struct gpio_desc *desc;
-       unsigned int i;
-
-       /* Try GPIO property "foo-gpios" and "foo-gpio" */
-       for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
-               if (con_id)
-                       snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id,
-                                gpio_suffixes[i]);
-               else
-                       snprintf(prop_name, sizeof(prop_name), "%s",
-                                gpio_suffixes[i]);
-
-               desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
-                                               &of_flags);
-
-               if (!IS_ERR(desc) || PTR_ERR(desc) != -ENOENT)
-                       break;
-       }
+       enum of_gpio_flags of_flags;
 
-       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
-               /* Special handling for SPI GPIOs if used */
-               desc = of_find_spi_gpio(dev, con_id, &of_flags);
-       }
+       /* Special handling for SPI GPIOs if used */
+       desc = of_find_spi_gpio(dev, con_id, &of_flags);
 
-       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
-               /* This quirk looks up flags and all */
-               desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
-               if (!IS_ERR(desc))
-                       return desc;
-       }
+       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
+               desc = of_find_spi_cs_gpio(dev, con_id, idx, &of_flags);
 
        if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
                /* Special handling for regulator GPIOs if used */
@@ -495,26 +514,8 @@ struct gpio_desc *of_find_gpio(struct device *dev, const 
char *con_id,
        if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
                desc = of_find_arizona_gpio(dev, con_id, &of_flags);
 
-       if (IS_ERR(desc))
-               return desc;
-
-       if (of_flags & OF_GPIO_ACTIVE_LOW)
-               *flags |= GPIO_ACTIVE_LOW;
-
-       if (of_flags & OF_GPIO_SINGLE_ENDED) {
-               if (of_flags & OF_GPIO_OPEN_DRAIN)
-                       *flags |= GPIO_OPEN_DRAIN;
-               else
-                       *flags |= GPIO_OPEN_SOURCE;
-       }
-
-       if (of_flags & OF_GPIO_TRANSITORY)
-               *flags |= GPIO_TRANSITORY;
-
-       if (of_flags & OF_GPIO_PULL_UP)
-               *flags |= GPIO_PULL_UP;
-       if (of_flags & OF_GPIO_PULL_DOWN)
-               *flags |= GPIO_PULL_DOWN;
+       if (!IS_ERR(desc))
+               of_gpio_flags_to_lookup(of_flags, flags);
 
        return desc;
 }
diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h
index 454d1658ee2d..580539cd995f 100644
--- a/drivers/gpio/gpiolib-of.h
+++ b/drivers/gpio/gpiolib-of.h
@@ -3,14 +3,17 @@
 #ifndef GPIOLIB_OF_H
 #define GPIOLIB_OF_H
 
+struct fwnode_handle;
 struct gpio_chip;
 enum of_gpio_flags;
 
 #ifdef CONFIG_OF_GPIO
-struct gpio_desc *of_find_gpio(struct device *dev,
-                              const char *con_id,
-                              unsigned int idx,
-                              unsigned long *lookupflags);
+struct gpio_desc *of_find_gpio(struct fwnode_handle *fwnode,
+                              const char *con_id, unsigned int idx,
+                              unsigned long *flags);
+struct gpio_desc *of_find_gpio_fallback(struct device *dev,
+                                       const char *con_id, unsigned int idx,
+                                       unsigned long *flags);
 struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
                   const char *list_name, int index, enum of_gpio_flags *flags);
 int of_gpiochip_add(struct gpio_chip *gc);
@@ -18,10 +21,17 @@ 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);
 #else
-static inline struct gpio_desc *of_find_gpio(struct device *dev,
-                                            const char *con_id,
-                                            unsigned int idx,
-                                            unsigned long *lookupflags)
+static inline
+struct gpio_desc *of_find_gpio(struct fwnode_handle *fwnode,
+                              const char *con_id, unsigned int idx,
+                              unsigned long *flags)
+{
+       return ERR_PTR(-ENOENT);
+}
+static inline
+struct gpio_desc *of_find_gpio_fallback(struct device *dev,
+                                       const char *con_id, unsigned int idx,
+                                       unsigned long *flags)
 {
        return ERR_PTR(-ENOENT);
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 54db2c42e9a0..1248e61f9a23 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -4562,7 +4562,12 @@ struct gpio_desc *__must_check gpiod_get_index(struct 
device *dev,
                /* Using device tree? */
                if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
                        dev_dbg(dev, "using device tree for GPIO lookup\n");
-                       desc = of_find_gpio(dev, con_id, idx, &lookupflags);
+                       desc = of_find_gpio(dev_fwnode(dev),
+                                           con_id, idx, &lookupflags);
+                       if (desc == ERR_PTR(-ENOENT))
+                               desc = of_find_gpio_fallback(dev, con_id, idx,
+                                                            &lookupflags);
+
                } else if (ACPI_COMPANION(dev)) {
                        dev_dbg(dev, "using ACPI for GPIO lookup\n");
                        desc = acpi_find_gpio(dev, con_id, idx, &flags, 
&lookupflags);
-- 
2.23.0.162.g0b9fbb3734-goog

Reply via email to