[PATCH 10/11] gpiolib: consolidate fwnode GPIO lookups

Dmitry Torokhov
2019-09-11T07:52:45Z

Ensure that all paths to obtain/look up GPIOD from generic
consumer-visible APIs go through the new fwnode_locate_gpiod(), so that
we can easily extend the support for new firmware mechanisms.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---

drivers/gpio/gpiolib-acpi.c | 88 +++++++++++++++----------------
drivers/gpio/gpiolib-acpi.h | 10 ----
drivers/gpio/gpiolib.c | 100 ++++++++++++------------------------
3 files changed, 77 insertions(+), 121 deletions(-)

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 8174db1bc02e..13907add5027 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -728,6 +728,50 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
return ret ? ERR_PTR(ret) : lookup.desc;
}

+/**
+ * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
+ * @fwnode: pointer to an ACPI firmware node to get the GPIO information from
+ * @propname: Property name of the GPIO
+ * @index: index of GpioIo/GpioInt resource (starting from %0)
+ * @info: info pointer to fill in (optional)
+ *
+ * If @fwnode is an ACPI device object, call acpi_get_gpiod_by_index() for it.
+ * Otherwise (i.e. it is a data-only non-device object), use the property-based
+ * GPIO lookup to get to the GPIO resource with the relevant information and use
+ * that to obtain the GPIO descriptor to return.
+ *
+ * If the GPIO cannot be translated or there is an error an ERR_PTR is
+ * returned.
+ */
+static struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+ const char *propname, int index,
+ struct acpi_gpio_info *info)
+{
+ struct acpi_gpio_lookup lookup;
+ struct acpi_device *adev;
+ int ret;
+
+ adev = to_acpi_device_node(fwnode);
+ if (adev)
+ return acpi_get_gpiod_by_index(adev, propname, index, info);
+
+ if (!is_acpi_data_node(fwnode))
+ return ERR_PTR(-ENODEV);
+
+ if (!propname)
+ return ERR_PTR(-EINVAL);
+
+ memset(&lookup, 0, sizeof(lookup));
+ lookup.index = index;
+
+ ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup);
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = acpi_gpio_resource_lookup(&lookup, info);
+ return ret ? ERR_PTR(ret) : lookup.desc;
+}
+
static int acpi_finalize_gpio_lookup(struct acpi_gpio_info *info,
enum gpiod_flags *dflags,
unsigned long *lookupflags)
@@ -815,50 +859,6 @@ struct gpio_desc *acpi_find_gpio_fallback(struct acpi_device *adev,
return desc;
}

-/**
- * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources
- * @fwnode: pointer to an ACPI firmware node to get the GPIO information from
- * @propname: Property name of the GPIO
- * @index: index of GpioIo/GpioInt resource (starting from %0)
- * @info: info pointer to fill in (optional)
- *
- * If @fwnode is an ACPI device object, call acpi_get_gpiod_by_index() for it.
- * Otherwise (i.e. it is a data-only non-device object), use the property-based
- * GPIO lookup to get to the GPIO resource with the relevant information and use
- * that to obtain the GPIO descriptor to return.
- *
- * If the GPIO cannot be translated or there is an error an ERR_PTR is
- * returned.
- */
-struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
- const char *propname, int index,
- struct acpi_gpio_info *info)
-{
- struct acpi_gpio_lookup lookup;
- struct acpi_device *adev;
- int ret;
-
- adev = to_acpi_device_node(fwnode);
- if (adev)
- return acpi_get_gpiod_by_index(adev, propname, index, info);
-
- if (!is_acpi_data_node(fwnode))
- return ERR_PTR(-ENODEV);
-
- if (!propname)
- return ERR_PTR(-EINVAL);
-
- memset(&lookup, 0, sizeof(lookup));
- lookup.index = index;
-
- ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup);
- if (ret)
- return ERR_PTR(ret);
-
- ret = acpi_gpio_resource_lookup(&lookup, info);
- return ret ? ERR_PTR(ret) : lookup.desc;
-}
-
/**
* acpi_dev_gpio_irq_get() - Find GpioInt and translate it to Linux IRQ number
* @adev: pointer to a ACPI device to get IRQ from
diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h
index ea97a3822116..047df1d5c7fa 100644
--- a/drivers/gpio/gpiolib-acpi.h
+++ b/drivers/gpio/gpiolib-acpi.h
@@ -53,10 +53,6 @@ struct gpio_desc *acpi_find_gpio_fallback(struct acpi_device *adev,
unsigned int idx,
enum gpiod_flags *dflags,
unsigned long *lookupflags);
-struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
- const char *propname, int index,
- struct acpi_gpio_info *info);
-
int acpi_gpio_count(struct device *dev, const char *con_id);
#else
static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
@@ -94,12 +90,6 @@ acpi_find_gpio_fallback(struct acpi_device *adev, const char *con_id,
{
return ERR_PTR(-ENOENT);
}
-static inline struct gpio_desc *
-acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
- int index, struct acpi_gpio_info *info)
-{
- return ERR_PTR(-ENXIO);
-}
static inline int acpi_gpio_count(struct device *dev, const char *con_id)
{
return -ENODEV;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 2d8dd67ab03d..6534dcd6e406 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -4314,44 +4314,27 @@ static int platform_gpio_count(struct device *dev, const char *con_id)
return count;
}

-static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
- const char *propname, int index,
- enum gpiod_flags dflags,
- const char *label)
+static struct gpio_desc *fwnode_locate_gpiod(struct fwnode_handle *fwnode,
+ struct device *dev,
+ const char *con_id, int idx,
+ enum gpiod_flags *flags,
+ unsigned long *lookupflags)
{
- unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
struct gpio_desc *desc = ERR_PTR(-ENODEV);
- int ret;
-
- if (!fwnode)
- return ERR_PTR(-EINVAL);

if (is_of_node(fwnode)) {
- desc = gpiod_get_from_of_node(to_of_node(fwnode),
- propname, index,
- dflags,
- label);
- return desc;
+ dev_dbg(dev, "using device tree for GPIO lookup\n");
+ desc = of_find_gpio(fwnode, con_id, idx, lookupflags);
+ if (desc == ERR_PTR(-ENOENT) && dev)
+ desc = of_find_gpio_fallback(dev, con_id, idx,
+ lookupflags);
} else if (is_acpi_node(fwnode)) {
- struct acpi_gpio_info info;
-
- desc = acpi_node_get_gpiod(fwnode, propname, index, &info);
- if (IS_ERR(desc))
- return desc;
-
- acpi_gpio_update_gpiod_flags(&dflags, &info);
- acpi_gpio_update_gpiod_lookup_flags(&lflags, &info);
- }
-
- /* Currently only ACPI takes this path */
- ret = gpiod_request(desc, label);
- if (ret)
- return ERR_PTR(ret);
-
- ret = gpiod_configure_flags(desc, propname, lflags, dflags);
- if (ret < 0) {
- gpiod_put(desc);
- return ERR_PTR(ret);
+ dev_dbg(dev, "using ACPI for GPIO lookup\n");
+ desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags);
+ if (desc == ERR_PTR(-ENOENT) && dev)
+ desc = acpi_find_gpio_fallback(ACPI_COMPANION(dev),
+ con_id, idx,
+ flags, lookupflags);
}

return desc;
@@ -4383,22 +4366,23 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode,
enum gpiod_flags flags,
const char *label)
{
+ unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
struct gpio_desc *desc;
- char prop_name[32]; /* 32 is max size of property name */
- unsigned int i;
+ int error;

- 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 = fwnode_locate_gpiod(fwnode, NULL, con_id, index,
+ &flags, &lookupflags);
+ if (IS_ERR(desc))
+ return desc;

- desc = fwnode_get_named_gpiod(fwnode, prop_name, index, flags,
- label);
- if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
- break;
+ error = gpiod_request(desc, label);
+ if (error)
+ return ERR_PTR(error);
+
+ error = gpiod_configure_flags(desc, con_id, lookupflags, flags);
+ if (error < 0) {
+ gpiod_put(desc);
+ return ERR_PTR(error);
}

return desc;
@@ -4558,27 +4542,9 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,

dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);

- if (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_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_fwnode(dev), con_id, idx,
- &flags, &lookupflags);
- if (desc == ERR_PTR(-ENOENT))
- desc = acpi_find_gpio_fallback(
- ACPI_COMPANION(dev),
- con_id, idx,
- &flags, &lookupflags);
- }
- }
+ if (dev)
+ desc = fwnode_locate_gpiod(dev_fwnode(dev), dev, con_id, idx,
+ &flags, &lookupflags);

/*
* Either we are not using DT or ACPI, or their lookup did not return
--
2.23.0.162.g0b9fbb3734-goog