Linux-ACPI Archive on lore.kernel.org
 help / color / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
	Bartosz Golaszewski <bgolaszewski@baylibre.com>,
	linux-acpi@vger.kernel.org
Subject: [PATCH 09/11] gpiolib: of: tease apart acpi_find_gpio()
Date: Wed, 11 Sep 2019 00:52:13 -0700
Message-ID: <20190911075215.78047-10-dmitry.torokhov@gmail.com> (raw)
In-Reply-To: <20190911075215.78047-1-dmitry.torokhov@gmail.com>

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

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

 drivers/gpio/gpiolib-acpi.c | 77 +++++++++++++++++++++++++------------
 drivers/gpio/gpiolib-acpi.h | 17 +++++++-
 drivers/gpio/gpiolib.c      |  8 +++-
 3 files changed, 74 insertions(+), 28 deletions(-)

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 2b6fdc9947f7..8174db1bc02e 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -728,29 +728,35 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
 	return ret ? ERR_PTR(ret) : lookup.desc;
 }
 
-static bool acpi_can_fallback_to_crs(struct acpi_device *adev,
-				     const char *con_id)
+static int acpi_finalize_gpio_lookup(struct acpi_gpio_info *info,
+				     enum gpiod_flags *dflags,
+				     unsigned long *lookupflags)
 {
-	/* Never allow fallback if the device has properties */
-	if (acpi_dev_has_props(adev) || adev->driver_gpios)
-		return false;
+	if (info->gpioint &&
+	    (*dflags == GPIOD_OUT_LOW || *dflags == GPIOD_OUT_HIGH)) {
+		dev_dbg(&info->adev->dev,
+			"refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
+		return -ENOENT;
+	}
 
-	return con_id == NULL;
+	acpi_gpio_update_gpiod_flags(dflags, info);
+	acpi_gpio_update_gpiod_lookup_flags(lookupflags, info);
+
+	return 0;
 }
 
-struct gpio_desc *acpi_find_gpio(struct device *dev,
-				 const char *con_id,
-				 unsigned int idx,
+struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
+				 const char *con_id, unsigned int idx,
 				 enum gpiod_flags *dflags,
 				 unsigned long *lookupflags)
 {
-	struct acpi_device *adev = ACPI_COMPANION(dev);
 	struct acpi_gpio_info info;
 	struct gpio_desc *desc;
 	char propname[32];
 	int i;
+	int error;
 
-	/* Try first from _DSD */
+	/* Try GPIOs from _DSD */
 	for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
 		if (con_id) {
 			snprintf(propname, sizeof(propname), "%s-%s",
@@ -760,31 +766,52 @@ struct gpio_desc *acpi_find_gpio(struct device *dev,
 				 gpio_suffixes[i]);
 		}
 
-		desc = acpi_get_gpiod_by_index(adev, propname, idx, &info);
+		desc = acpi_node_get_gpiod(fwnode, propname, idx, &info);
 		if (!IS_ERR(desc))
 			break;
 		if (PTR_ERR(desc) == -EPROBE_DEFER)
 			return ERR_CAST(desc);
 	}
 
-	/* Then from plain _CRS GPIOs */
-	if (IS_ERR(desc)) {
-		if (!acpi_can_fallback_to_crs(adev, con_id))
-			return ERR_PTR(-ENOENT);
-
-		desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
-		if (IS_ERR(desc))
-			return desc;
+	if (!IS_ERR(desc)) {
+		error = acpi_finalize_gpio_lookup(&info, dflags, lookupflags);
+		if (error)
+			return ERR_PTR(error);
 	}
 
-	if (info.gpioint &&
-	    (*dflags == GPIOD_OUT_LOW || *dflags == GPIOD_OUT_HIGH)) {
-		dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n");
+	return desc;
+}
+
+static bool acpi_can_fallback_to_crs(struct acpi_device *adev,
+				     const char *con_id)
+{
+	/* Never allow fallback if the device has properties */
+	if (acpi_dev_has_props(adev) || adev->driver_gpios)
+		return false;
+
+	return con_id == NULL;
+}
+
+struct gpio_desc *acpi_find_gpio_fallback(struct acpi_device *adev,
+					  const char *con_id, unsigned int idx,
+					  enum gpiod_flags *dflags,
+					  unsigned long *lookupflags)
+{
+	struct acpi_gpio_info info;
+	struct gpio_desc *desc;
+	int error;
+
+	/* Then from plain _CRS GPIOs */
+	if (!acpi_can_fallback_to_crs(adev, con_id))
 		return ERR_PTR(-ENOENT);
+
+	desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info);
+	if (!IS_ERR(desc)) {
+		error = acpi_finalize_gpio_lookup(&info, dflags, lookupflags);
+		if (error)
+			return ERR_PTR(error);
 	}
 
-	acpi_gpio_update_gpiod_flags(dflags, &info);
-	acpi_gpio_update_gpiod_lookup_flags(lookupflags, &info);
 	return desc;
 }
 
diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h
index 1c6d65cf0629..ea97a3822116 100644
--- a/drivers/gpio/gpiolib-acpi.h
+++ b/drivers/gpio/gpiolib-acpi.h
@@ -9,6 +9,7 @@
 #define GPIOLIB_ACPI_H
 
 struct acpi_device;
+struct fwnode_handle;
 
 /**
  * struct acpi_gpio_info - ACPI GPIO specific information
@@ -42,11 +43,16 @@ int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags,
 int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
 					struct acpi_gpio_info *info);
 
-struct gpio_desc *acpi_find_gpio(struct device *dev,
+struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode,
 				 const char *con_id,
 				 unsigned int idx,
 				 enum gpiod_flags *dflags,
 				 unsigned long *lookupflags);
+struct gpio_desc *acpi_find_gpio_fallback(struct acpi_device *adev,
+					  const char *con_id,
+					  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);
@@ -75,13 +81,20 @@ acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
 }
 
 static inline struct gpio_desc *
-acpi_find_gpio(struct device *dev, const char *con_id,
+acpi_find_gpio(struct firmware_node *fwnode, const char *con_id,
 	       unsigned int idx, enum gpiod_flags *dflags,
 	       unsigned long *lookupflags)
 {
 	return ERR_PTR(-ENOENT);
 }
 static inline struct gpio_desc *
+acpi_find_gpio_fallback(struct acpi_device *adev, const char *con_id,
+			unsigned int idx, enum gpiod_flags *dflags,
+			unsigned long *lookupflags)
+{
+	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)
 {
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 1248e61f9a23..2d8dd67ab03d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -4570,7 +4570,13 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
 
 		} else if (ACPI_COMPANION(dev)) {
 			dev_dbg(dev, "using ACPI for GPIO lookup\n");
-			desc = acpi_find_gpio(dev, con_id, idx, &flags, &lookupflags);
+			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);
 		}
 	}
 
-- 
2.23.0.162.g0b9fbb3734-goog


  reply index

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-11  7:52 [PATCH 00/11] Add support for software nodes to gpiolib Dmitry Torokhov
2019-09-11  7:52 ` Dmitry Torokhov [this message]
2019-09-11 17:12   ` [PATCH 09/11] gpiolib: of: tease apart acpi_find_gpio() Andy Shevchenko
2019-09-11  7:52 ` [PATCH 10/11] gpiolib: consolidate fwnode GPIO lookups Dmitry Torokhov
2019-09-11 17:13 ` [PATCH 00/11] Add support for software nodes to gpiolib Andy Shevchenko
2019-09-12  9:55 ` Linus Walleij

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190911075215.78047-10-dmitry.torokhov@gmail.com \
    --to=dmitry.torokhov@gmail.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-ACPI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-acpi/0 linux-acpi/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-acpi linux-acpi/ https://lore.kernel.org/linux-acpi \
		linux-acpi@vger.kernel.org linux-acpi@archiver.kernel.org
	public-inbox-index linux-acpi


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-acpi


AGPL code for this site: git clone https://public-inbox.org/ public-inbox