gpiolib: of: consolidate simple renames into a single quirk
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 18 Oct 2022 05:41:03 +0000 (22:41 -0700)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Thu, 20 Oct 2022 11:53:19 +0000 (13:53 +0200)
This consolidates all quirks doing simple renames (either allowing
suffix-less names or trivial renames, when index changes are not
required) into a single quirk.

Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/gpiolib-of.c

index cef4f66341256fadc39d3d2b093efb94888a8efc..63c6fa3086f3c8f803bd6a6ab2cb831d7181e164 100644 (file)
@@ -365,127 +365,90 @@ struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(gpiod_get_from_of_node);
 
-/*
- * 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
- * them.
- */
-static struct gpio_desc *of_find_spi_gpio(struct device_node *np,
-                                         const char *con_id,
-                                         unsigned int idx,
-                                         enum of_gpio_flags *of_flags)
-{
-       char prop_name[32]; /* 32 is max size of property name */
-
-       /*
-        * Hopefully the compiler stubs the rest of the function if this
-        * is false.
-        */
-       if (!IS_ENABLED(CONFIG_SPI_MASTER))
-               return ERR_PTR(-ENOENT);
-
-       /* Allow this specifically for "spi-gpio" devices */
-       if (!of_device_is_compatible(np, "spi-gpio") || !con_id)
-               return ERR_PTR(-ENOENT);
-
-       /* Will be "gpio-sck", "gpio-mosi" or "gpio-miso" */
-       snprintf(prop_name, sizeof(prop_name), "%s-%s", "gpio", con_id);
-
-       return of_get_named_gpiod_flags(np, prop_name, idx, of_flags);
-}
-
-/*
- * The old Freescale bindings use simply "gpios" as name for the chip select
- * lines rather than "cs-gpios" like all other SPI hardware. Account for this
- * with a special quirk.
- */
-static struct gpio_desc *of_find_spi_cs_gpio(struct device_node *np,
+static struct gpio_desc *of_find_gpio_rename(struct device_node *np,
                                             const char *con_id,
                                             unsigned int idx,
                                             enum of_gpio_flags *of_flags)
 {
-       if (!IS_ENABLED(CONFIG_SPI_MASTER))
-               return ERR_PTR(-ENOENT);
-
-       /* Allow this specifically for Freescale and PPC devices */
-       if (!of_device_is_compatible(np, "fsl,spi") &&
-           !of_device_is_compatible(np, "aeroflexgaisler,spictrl") &&
-           !of_device_is_compatible(np, "ibm,ppc4xx-spi"))
-               return ERR_PTR(-ENOENT);
-       /* Allow only if asking for "cs-gpios" */
-       if (!con_id || strcmp(con_id, "cs"))
-               return ERR_PTR(-ENOENT);
+       static const struct of_rename_gpio {
+               const char *con_id;
+               const char *legacy_id;  /* NULL - same as con_id */
+               /*
+                * Compatible string can be set to NULL in case where
+                * matching to a particular compatible is not practical,
+                * but it should only be done for gpio names that have
+                * vendor prefix to reduce risk of false positives.
+                * Addition of such entries is strongly discouraged.
+                */
+               const char *compatible;
+       } gpios[] = {
+#if IS_ENABLED(CONFIG_MFD_ARIZONA)
+               { "wlf,reset",  NULL,           NULL },
+#endif
+#if IS_ENABLED(CONFIG_REGULATOR)
+               /*
+                * Some regulator bindings happened before we managed to
+                * establish that GPIO properties should be named
+                * "foo-gpios" so we have this special kludge for them.
+                */
+               { "wlf,ldoena",  NULL,          NULL }, /* Arizona */
+               { "wlf,ldo1ena", NULL,          NULL }, /* WM8994 */
+               { "wlf,ldo2ena", NULL,          NULL }, /* WM8994 */
+#endif
+#if IS_ENABLED(CONFIG_SPI_MASTER)
 
-       /*
-        * While all other SPI controllers use "cs-gpios" the Freescale
-        * uses just "gpios" so translate to that when "cs-gpios" is
-        * requested.
-        */
-       return of_get_named_gpiod_flags(np, "gpios", idx, of_flags);
-}
+               /*
+                * 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 them.
+                */
+               { "miso",       "gpio-miso",    "spi-gpio" },
+               { "mosi",       "gpio-mosi",    "spi-gpio" },
+               { "sck",        "gpio-sck",     "spi-gpio" },
 
-/*
- * Some regulator bindings happened before we managed to establish that GPIO
- * properties should be named "foo-gpios" so we have this special kludge for
- * them.
- */
-static struct gpio_desc *of_find_regulator_gpio(struct device_node *np,
-                                               const char *con_id,
-                                               unsigned int idx,
-                                               enum of_gpio_flags *of_flags)
-{
-       /* These are the connection IDs we accept as legacy GPIO phandles */
-       const char *whitelist[] = {
-               "wlf,ldoena", /* Arizona */
-               "wlf,ldo1ena", /* WM8994 */
-               "wlf,ldo2ena", /* WM8994 */
+               /*
+                * The old Freescale bindings use simply "gpios" as name
+                * for the chip select lines rather than "cs-gpios" like
+                * all other SPI hardware. Allow this specifically for
+                * Freescale and PPC devices.
+                */
+               { "cs",         "gpios",        "fsl,spi" },
+               { "cs",         "gpios",        "aeroflexgaisler,spictrl" },
+               { "cs",         "gpios",        "ibm,ppc4xx-spi" },
+#endif
+#if IS_ENABLED(CONFIG_TYPEC_FUSB302)
+               /*
+                * Fairchild FUSB302 host is using undocumented "fcs,int_n"
+                * property without the compulsory "-gpios" suffix.
+                */
+               { "fcs,int_n",  NULL,           "fcs,fusb302" },
+#endif
        };
-       int i;
-
-       if (!IS_ENABLED(CONFIG_REGULATOR))
-               return ERR_PTR(-ENOENT);
+       struct gpio_desc *desc;
+       const char *legacy_id;
+       unsigned int i;
 
        if (!con_id)
                return ERR_PTR(-ENOENT);
 
-       i = match_string(whitelist, ARRAY_SIZE(whitelist), con_id);
-       if (i < 0)
-               return ERR_PTR(-ENOENT);
-
-       return of_get_named_gpiod_flags(np, con_id, idx, of_flags);
-}
-
-static struct gpio_desc *of_find_arizona_gpio(struct device_node *np,
-                                             const char *con_id,
-                                             unsigned int idx,
-                                             enum of_gpio_flags *of_flags)
-{
-       if (!IS_ENABLED(CONFIG_MFD_ARIZONA))
-               return ERR_PTR(-ENOENT);
-
-       if (!con_id || strcmp(con_id, "wlf,reset"))
-               return ERR_PTR(-ENOENT);
-
-       return of_get_named_gpiod_flags(np, con_id, idx, of_flags);
-}
+       for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+               if (strcmp(con_id, gpios[i].con_id))
+                       continue;
 
-static struct gpio_desc *of_find_usb_gpio(struct device_node *np,
-                                         const char *con_id,
-                                         unsigned int idx,
-                                         enum of_gpio_flags *of_flags)
-{
-       /*
-        * Currently this USB quirk is only for the Fairchild FUSB302 host
-        * which is using an undocumented DT GPIO line named "fcs,int_n"
-        * without the compulsory "-gpios" suffix.
-        */
-       if (!IS_ENABLED(CONFIG_TYPEC_FUSB302))
-               return ERR_PTR(-ENOENT);
+               if (gpios[i].compatible &&
+                   !of_device_is_compatible(np, gpios[i].compatible))
+                       continue;
 
-       if (!con_id || strcmp(con_id, "fcs,int_n"))
-               return ERR_PTR(-ENOENT);
+               legacy_id = gpios[i].legacy_id ?: gpios[i].con_id;
+               desc = of_get_named_gpiod_flags(np, legacy_id, idx, of_flags);
+               if (!gpiod_not_found(desc)) {
+                       pr_info("%s uses legacy gpio name '%s' instead of '%s-gpios'\n",
+                               of_node_full_name(np), legacy_id, con_id);
+                       return desc;
+               }
+       }
 
-       return of_get_named_gpiod_flags(np, con_id, idx, of_flags);
+       return ERR_PTR(-ENOENT);
 }
 
 static struct gpio_desc *of_find_mt2701_gpio(struct device_node *np,
@@ -525,11 +488,7 @@ typedef struct gpio_desc *(*of_find_gpio_quirk)(struct device_node *np,
                                                unsigned int idx,
                                                enum of_gpio_flags *of_flags);
 static const of_find_gpio_quirk of_find_gpio_quirks[] = {
-       of_find_spi_gpio,
-       of_find_spi_cs_gpio,
-       of_find_regulator_gpio,
-       of_find_arizona_gpio,
-       of_find_usb_gpio,
+       of_find_gpio_rename,
        of_find_mt2701_gpio,
        NULL
 };