From: Mika Westerberg <mika.westerberg@linux.intel.com>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>,
Heikki Krogerus <heikki.krogerus@linux.intel.com>,
Mathias Nyman <mathias.nyman@linux.intel.com>,
"Rafael J. Wysocki" <rjw@rjwysocki.net>,
Ning Li <ning.li@intel.com>, Alan Cox <alan@linux.intel.com>,
Mika Westerberg <mika.westerberg@linux.intel.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 1/2] gpio / ACPI: Add knowledge about pin controllers to acpi_get_gpiod()
Date: Mon, 3 Nov 2014 13:01:32 +0200 [thread overview]
Message-ID: <1415012493-134561-2-git-send-email-mika.westerberg@linux.intel.com> (raw)
In-Reply-To: <1415012493-134561-1-git-send-email-mika.westerberg@linux.intel.com>
The GPIO resources (GpioIo/GpioInt) used in ACPI contain a GPIO number
which is relative to the hardware GPIO controller. Typically this number
can be translated directly to Linux GPIO number because the mapping is
pretty much 1:1.
However, when the GPIO driver is using pins exported by a pin controller
driver via set of GPIO ranges, the mapping might not be 1:1 anymore and
direct translation does not work.
In such cases we need to translate the ACPI GPIO number to be suitable for
the GPIO controller driver in question by checking all the pin controller
GPIO ranges under the given device and using those to get the proper GPIO
number.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/gpio/gpiolib-acpi.c | 62 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 59 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 05c6275da224..5be637dffa73 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -11,12 +11,14 @@
*/
#include <linux/errno.h>
+#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/export.h>
#include <linux/acpi.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
+#include <linux/pinctrl/pinctrl.h>
#include "gpiolib.h"
@@ -55,6 +57,58 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
return ACPI_HANDLE(gc->dev) == data;
}
+#ifdef CONFIG_PINCTRL
+/**
+ * acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO
+ * @chip: GPIO chip
+ * @pin: ACPI GPIO pin number from GpioIo/GpioInt resource
+ *
+ * Function takes ACPI GpioIo/GpioInt pin number as a parameter and
+ * translates it to a corresponding offset suitable to be passed to a
+ * GPIO controller driver.
+ *
+ * Typically the returned offset is same as @pin, but if the GPIO
+ * controller uses pin controller and the mapping is not contigous the
+ * offset might be different.
+ */
+static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin)
+{
+ struct gpio_pin_range *pin_range;
+
+ /* If there are no ranges in this chip, use 1:1 mapping */
+ if (list_empty(&chip->pin_ranges))
+ return pin;
+
+ list_for_each_entry(pin_range, &chip->pin_ranges, node) {
+ const struct pinctrl_gpio_range *range = &pin_range->range;
+ int i;
+
+ if (range->pins) {
+ for (i = 0; i < range->npins; i++) {
+ if (range->pins[i] == pin)
+ return range->base + i - chip->base;
+ }
+ } else {
+ if (pin >= range->pin_base &&
+ pin < range->pin_base + range->npins) {
+ unsigned gpio_base;
+
+ gpio_base = range->base - chip->base;
+ return gpio_base + pin - range->pin_base;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+#else
+static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip,
+ int pin)
+{
+ return pin;
+}
+#endif
+
/**
* acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API
* @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
@@ -69,6 +123,7 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
struct gpio_chip *chip;
acpi_handle handle;
acpi_status status;
+ int offset;
status = acpi_get_handle(NULL, path, &handle);
if (ACPI_FAILURE(status))
@@ -78,10 +133,11 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
if (!chip)
return ERR_PTR(-ENODEV);
- if (pin < 0 || pin > chip->ngpio)
- return ERR_PTR(-EINVAL);
+ offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin);
+ if (offset < 0)
+ return ERR_PTR(offset);
- return gpiochip_get_desc(chip, pin);
+ return gpiochip_get_desc(chip, offset);
}
static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
--
2.1.1
next prev parent reply other threads:[~2014-11-03 11:04 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-03 11:01 [PATCH v2 0/2] pinctrl: Intel Cherryview/Braswell support Mika Westerberg
2014-11-03 11:01 ` Mika Westerberg [this message]
2014-11-04 10:18 ` [PATCH v2 1/2] gpio / ACPI: Add knowledge about pin controllers to acpi_get_gpiod() Linus Walleij
2014-11-03 11:01 ` [PATCH v2 2/2] pinctrl: Add Intel Cherryview/Braswell pin controller support Mika Westerberg
2014-11-04 10:23 ` Linus Walleij
2014-11-03 23:24 ` [PATCH v2 0/2] pinctrl: Intel Cherryview/Braswell support Timur Tabi
2014-11-04 8:20 ` Mika Westerberg
2014-11-04 9:39 ` Mika Westerberg
2014-11-04 13:31 ` Rafael J. Wysocki
2014-11-04 13:48 ` Linus Walleij
2014-11-04 14:16 ` Rafael J. Wysocki
2014-11-04 14:12 ` Mika Westerberg
2014-11-04 16:37 ` Timur Tabi
2014-11-04 21:51 ` Timur Tabi
2014-11-04 22:47 ` Rafael J. Wysocki
2014-11-04 22:32 ` Timur Tabi
2014-11-04 22:39 ` Timur Tabi
2014-11-04 23:13 ` Rafael J. Wysocki
2014-11-04 22:56 ` Timur Tabi
2014-11-04 23:18 ` Timur Tabi
2014-11-05 21:04 ` Rafael J. Wysocki
2014-11-05 21:19 ` Rafael J. Wysocki
2014-11-04 23:00 ` Rafael J. Wysocki
2014-11-04 17:54 ` Timur Tabi
2014-11-04 19:04 ` Mika Westerberg
2014-11-06 19:30 ` Linus Walleij
2014-11-05 21:46 ` Grant Likely
2014-11-05 21:59 ` Timur Tabi
2014-11-05 22:15 ` Rafael J. Wysocki
2014-11-06 17:37 ` Grant Likely
2014-11-06 18:01 ` Timur Tabi
2014-11-07 23:12 ` Timur Tabi
2014-11-06 19:28 ` Linus Walleij
2014-11-05 21:44 ` Olof Johansson
2014-11-06 6:07 ` Mika Westerberg
Reply instructions:
You may reply publicly 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=1415012493-134561-2-git-send-email-mika.westerberg@linux.intel.com \
--to=mika.westerberg@linux.intel.com \
--cc=alan@linux.intel.com \
--cc=gnurou@gmail.com \
--cc=heikki.krogerus@linux.intel.com \
--cc=linus.walleij@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathias.nyman@linux.intel.com \
--cc=ning.li@intel.com \
--cc=rjw@rjwysocki.net \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®