diff mbox series

[10/11] gpiolib: consolidate fwnode GPIO lookups

Message ID 20190911075215.78047-11-dmitry.torokhov@gmail.com
State New
Headers show
Series Add support for software nodes to gpiolib | expand

Commit Message

Dmitry Torokhov Sept. 11, 2019, 7:52 a.m. UTC
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 mbox series

Patch

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