From 2bd261dd1712561b8363fbf6f9f630176fe99caa Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Fri, 22 May 2020 11:08:59 +0200 Subject: [PATCH] gpio: search for gpio label if gpio is not found through bank name dm_gpio_lookup_name() searches for a gpio through the bank name. But we have also gpio labels, and it makes sense to search for a gpio also in the labels we have defined, if no gpio is found through the bank name definition. This is useful for example if you have a wp pin on different gpios on different board versions. If dm_gpio_lookup_name() searches also for the gpio labels, you can give the gpio an unique label name and search for this label, and do not need to differ between board revisions. Signed-off-by: Heiko Schocher Reviewed-by: Simon Glass [trini: Don't enable by default] Signed-off-by: Tom Rini --- drivers/gpio/Kconfig | 20 +++++++++++++++++ drivers/gpio/gpio-uclass.c | 46 ++++++++++++++++++++++++++++++++++++++ test/dm/gpio.c | 9 ++++++++ 3 files changed, 75 insertions(+) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index af608b7b0e..0e8ad9530d 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -46,6 +46,26 @@ config GPIO_HOG is a mechanism providing automatic GPIO request and config- uration as part of the gpio-controller's driver probe function. +config DM_GPIO_LOOKUP_LABEL + bool "Enable searching for gpio labelnames" + depends on DM_GPIO + help + This option enables searching for gpio names in + the defined gpio labels, if the search for the + gpio bank name failed. This makes sense if you use + different gpios on different hardware versions + for the same functionality in board code. + +config SPL_DM_GPIO_LOOKUP_LABEL + bool "Enable searching for gpio labelnames" + depends on DM_GPIO && SPL_DM && SPL_GPIO_SUPPORT + help + This option enables searching for gpio names in + the defined gpio labels, if the search for the + gpio bank name failed. This makes sense if you use + different gpios on different hardware versions + for the same functionality in board code. + config ALTERA_PIO bool "Altera PIO driver" depends on DM_GPIO diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index f016532354..ab17fa8a5d 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -68,6 +68,45 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) return ret ? ret : -ENOENT; } +#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL) +/** + * dm_gpio_lookup_label() - look for name in gpio device + * + * search in uc_priv, if there is a gpio with labelname same + * as name. + * + * @name: name which is searched + * @uc_priv: gpio_dev_priv pointer. + * @offset: gpio offset within the device + * @return: 0 if found, -ENOENT if not. + */ +static int dm_gpio_lookup_label(const char *name, + struct gpio_dev_priv *uc_priv, ulong *offset) +{ + int len; + int i; + + *offset = -1; + len = strlen(name); + for (i = 0; i < uc_priv->gpio_count; i++) { + if (!uc_priv->name[i]) + continue; + if (!strncmp(name, uc_priv->name[i], len)) { + *offset = i; + return 0; + } + } + return -ENOENT; +} +#else +static int +dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv, + ulong *offset) +{ + return -ENOENT; +} +#endif + int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) { struct gpio_dev_priv *uc_priv = NULL; @@ -96,6 +135,13 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) if (!strict_strtoul(name + len, 10, &offset)) break; } + + /* + * if we did not found a gpio through its bank + * name, we search for a valid gpio label. + */ + if (!dm_gpio_lookup_label(name, uc_priv, &offset)) + break; } if (!dev) diff --git a/test/dm/gpio.c b/test/dm/gpio.c index ecba566983..fcee1fe598 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -132,6 +132,15 @@ static int dm_test_gpio(struct unit_test_state *uts) ut_assertok(dm_gpio_set_value(desc, 0)); ut_asserteq(0, dm_gpio_get_value(desc)); + /* Check if lookup for labels work */ + ut_assertok(gpio_lookup_name("hog_input_active_low", &dev, &offset, + &gpio)); + ut_asserteq_str(dev->name, "base-gpios"); + ut_asserteq(0, offset); + ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 0, gpio); + ut_assert(gpio_lookup_name("hog_not_exist", &dev, &offset, + &gpio)); + return 0; } DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- 2.39.5