diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 13:43:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 13:43:14 -0500 |
commit | c1b30e4d9466000c0e287e9245d4397da4d7d2f9 (patch) | |
tree | 18ac4c6bb435202cee8e7281f58b0c72f7fa0144 /drivers/gpio/gpiolib-acpi.c | |
parent | 92a578b064d0227a3a7fbbdb9e29dbab7f8d400e (diff) | |
parent | 853b6bf044dcced57c523dbddabf8942e907be6e (diff) |
Merge tag 'pinctrl-v3.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control changes from Linus Walleij:
"Here is a stash of pin control changes I have collected for the v3.19
series. Mainly new hardware support, with Intels new embedded SoC as
the especially interesting thing standing out, fully using the
subsystem.
- Force conversion of the ux500 pin control device trees and parsers
to use the generic pin control bindings.
- New driver and device tree bindings for the Qualcomm PMIC MPP pin
controller and GPIO.
- Some ACPI infrastructure for pin controllers.
- New driver for the Intel CherryView/Braswell pin controller, the
first Intel pin controller to fully take advantage of the pin
control subsystem.
- Support the Freescale i.MX VF610 variant.
- Support the sunxi A80 variant.
- Support the Samsung Exynos 4415 and Exynos 7 variants.
- Split out Intel pin controllers to their own subdirectory.
- A large slew of rockchip pin control updates, including
suspend/resume support.
- A large slew of Samsung Exynos pin controller updates.
- Various minor updates and fixes"
* tag 'pinctrl-v3.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (49 commits)
pinctrl: at91: enhance (debugfs) at91_gpio_dbg_show
pinctrl: meson: add device tree bindings documentation
gpio: tz1090: Fix error handling of irq_of_parse_and_map
pinctrl: tz1090-pinctrl.txt: Fix typo in binding
pinctrl: pinconf-generic: Declare dt_params/conf_items const
pinctrl: exynos: Add support for Exynos4415
pinctrl: exynos: Add initial driver data for Exynos7
pinctrl: exynos: Add irq_chip instance for Exynos7 wakeup interrupts
pinctrl: exynos: Consolidate irq domain callbacks
pinctrl: exynos: Generalize the eint16_31 demux code
pinctrl: samsung: Separate per-bank init and runtime data
pinctrl: samsung: Constify samsung_pin_ctrl struct
pinctrl: samsung: Constify samsung_pin_bank_type struct
pinctrl: samsung: Drop unused label field in samsung_pin_ctrl struct
pinctrl: samsung: Make samsung_pinctrl_get_soc_data use ERR_PTR()
pinctrl: Add Intel Cherryview/Braswell pin controller support
gpio / ACPI: Add knowledge about pin controllers to acpi_get_gpiod()
pinctrl: Fix path error in documentation
pinctrl: rockchip: save and restore gpio6_c6 pinmux in suspend/resume
pinctrl: rockchip: add suspend/resume functions
...
Diffstat (limited to 'drivers/gpio/gpiolib-acpi.c')
-rw-r--r-- | drivers/gpio/gpiolib-acpi.c | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index ba98bb59a58f..c3bdaff71c25 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c | |||
@@ -11,12 +11,14 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/gpio.h> | ||
14 | #include <linux/gpio/consumer.h> | 15 | #include <linux/gpio/consumer.h> |
15 | #include <linux/gpio/driver.h> | 16 | #include <linux/gpio/driver.h> |
16 | #include <linux/export.h> | 17 | #include <linux/export.h> |
17 | #include <linux/acpi.h> | 18 | #include <linux/acpi.h> |
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <linux/pinctrl/pinctrl.h> | ||
20 | 22 | ||
21 | #include "gpiolib.h" | 23 | #include "gpiolib.h" |
22 | 24 | ||
@@ -55,6 +57,58 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) | |||
55 | return ACPI_HANDLE(gc->dev) == data; | 57 | return ACPI_HANDLE(gc->dev) == data; |
56 | } | 58 | } |
57 | 59 | ||
60 | #ifdef CONFIG_PINCTRL | ||
61 | /** | ||
62 | * acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO | ||
63 | * @chip: GPIO chip | ||
64 | * @pin: ACPI GPIO pin number from GpioIo/GpioInt resource | ||
65 | * | ||
66 | * Function takes ACPI GpioIo/GpioInt pin number as a parameter and | ||
67 | * translates it to a corresponding offset suitable to be passed to a | ||
68 | * GPIO controller driver. | ||
69 | * | ||
70 | * Typically the returned offset is same as @pin, but if the GPIO | ||
71 | * controller uses pin controller and the mapping is not contigous the | ||
72 | * offset might be different. | ||
73 | */ | ||
74 | static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin) | ||
75 | { | ||
76 | struct gpio_pin_range *pin_range; | ||
77 | |||
78 | /* If there are no ranges in this chip, use 1:1 mapping */ | ||
79 | if (list_empty(&chip->pin_ranges)) | ||
80 | return pin; | ||
81 | |||
82 | list_for_each_entry(pin_range, &chip->pin_ranges, node) { | ||
83 | const struct pinctrl_gpio_range *range = &pin_range->range; | ||
84 | int i; | ||
85 | |||
86 | if (range->pins) { | ||
87 | for (i = 0; i < range->npins; i++) { | ||
88 | if (range->pins[i] == pin) | ||
89 | return range->base + i - chip->base; | ||
90 | } | ||
91 | } else { | ||
92 | if (pin >= range->pin_base && | ||
93 | pin < range->pin_base + range->npins) { | ||
94 | unsigned gpio_base; | ||
95 | |||
96 | gpio_base = range->base - chip->base; | ||
97 | return gpio_base + pin - range->pin_base; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | return -EINVAL; | ||
103 | } | ||
104 | #else | ||
105 | static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, | ||
106 | int pin) | ||
107 | { | ||
108 | return pin; | ||
109 | } | ||
110 | #endif | ||
111 | |||
58 | /** | 112 | /** |
59 | * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API | 113 | * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API |
60 | * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") | 114 | * @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) | |||
69 | struct gpio_chip *chip; | 123 | struct gpio_chip *chip; |
70 | acpi_handle handle; | 124 | acpi_handle handle; |
71 | acpi_status status; | 125 | acpi_status status; |
126 | int offset; | ||
72 | 127 | ||
73 | status = acpi_get_handle(NULL, path, &handle); | 128 | status = acpi_get_handle(NULL, path, &handle); |
74 | if (ACPI_FAILURE(status)) | 129 | if (ACPI_FAILURE(status)) |
@@ -78,10 +133,11 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin) | |||
78 | if (!chip) | 133 | if (!chip) |
79 | return ERR_PTR(-ENODEV); | 134 | return ERR_PTR(-ENODEV); |
80 | 135 | ||
81 | if (pin < 0 || pin > chip->ngpio) | 136 | offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin); |
82 | return ERR_PTR(-EINVAL); | 137 | if (offset < 0) |
138 | return ERR_PTR(offset); | ||
83 | 139 | ||
84 | return gpiochip_get_desc(chip, pin); | 140 | return gpiochip_get_desc(chip, offset); |
85 | } | 141 | } |
86 | 142 | ||
87 | static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) | 143 | static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) |