aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ruppert <christian.ruppert@abilis.com>2013-10-15 09:37:54 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-10-16 09:33:50 -0400
commit586a87e6edc936d6d3c3585af504b33b9c3f0a06 (patch)
treee3a8b9960ef9b6f9e28eaf235790889f5ddf886e
parentc8ce878206076b159ee9488133aa51314570da38 (diff)
pinctrl/gpio: non-linear GPIO ranges accesible from gpiolib
This patch adds the infrastructure required to register non-linear gpio ranges through gpiolib and the standard GPIO device tree bindings. Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio.txt40
-rw-r--r--drivers/gpio/gpiolib-of.c63
-rw-r--r--drivers/gpio/gpiolib.c47
-rw-r--r--drivers/pinctrl/core.c14
-rw-r--r--include/asm-generic/gpio.h10
-rw-r--r--include/linux/gpio.h10
-rw-r--r--include/linux/pinctrl/pinctrl.h3
7 files changed, 177 insertions, 10 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index 6cec6ff20d2e..0c85bb6e3a80 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -87,8 +87,10 @@ controllers. The gpio-ranges property described below represents this, and
87contains information structures as follows: 87contains information structures as follows:
88 88
89 gpio-range-list ::= <single-gpio-range> [gpio-range-list] 89 gpio-range-list ::= <single-gpio-range> [gpio-range-list]
90 single-gpio-range ::= 90 single-gpio-range ::= <numeric-gpio-range> | <named-gpio-range>
91 numeric-gpio-range ::=
91 <pinctrl-phandle> <gpio-base> <pinctrl-base> <count> 92 <pinctrl-phandle> <gpio-base> <pinctrl-base> <count>
93 named-gpio-range ::= <pinctrl-phandle> <gpio-base> '<0 0>'
92 gpio-phandle : phandle to pin controller node. 94 gpio-phandle : phandle to pin controller node.
93 gpio-base : Base GPIO ID in the GPIO controller 95 gpio-base : Base GPIO ID in the GPIO controller
94 pinctrl-base : Base pinctrl pin ID in the pin controller 96 pinctrl-base : Base pinctrl pin ID in the pin controller
@@ -97,6 +99,19 @@ contains information structures as follows:
97The "pin controller node" mentioned above must conform to the bindings 99The "pin controller node" mentioned above must conform to the bindings
98described in ../pinctrl/pinctrl-bindings.txt. 100described in ../pinctrl/pinctrl-bindings.txt.
99 101
102In case named gpio ranges are used (ranges with both <pinctrl-base> and
103<count> set to 0), the property gpio-ranges-group-names contains one string
104for every single-gpio-range in gpio-ranges:
105 gpiorange-names-list ::= <gpiorange-name> [gpiorange-names-list]
106 gpiorange-name : Name of the pingroup associated to the GPIO range in
107 the respective pin controller.
108
109Elements of gpiorange-names-list corresponding to numeric ranges contain
110the empty string. Elements of gpiorange-names-list corresponding to named
111ranges contain the name of a pin group defined in the respective pin
112controller. The number of pins/GPIOs in the range is the number of pins in
113that pin group.
114
100Previous versions of this binding required all pin controller nodes that 115Previous versions of this binding required all pin controller nodes that
101were referenced by any gpio-ranges property to contain a property named 116were referenced by any gpio-ranges property to contain a property named
102#gpio-range-cells with value <3>. This requirement is now deprecated. 117#gpio-range-cells with value <3>. This requirement is now deprecated.
@@ -104,7 +119,7 @@ However, that property may still exist in older device trees for
104compatibility reasons, and would still be required even in new device 119compatibility reasons, and would still be required even in new device
105trees that need to be compatible with older software. 120trees that need to be compatible with older software.
106 121
107Example: 122Example 1:
108 123
109 qe_pio_e: gpio-controller@1460 { 124 qe_pio_e: gpio-controller@1460 {
110 #gpio-cells = <2>; 125 #gpio-cells = <2>;
@@ -117,3 +132,24 @@ Example:
117Here, a single GPIO controller has GPIOs 0..9 routed to pin controller 132Here, a single GPIO controller has GPIOs 0..9 routed to pin controller
118pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's 133pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's
119pins 50..59. 134pins 50..59.
135
136Example 2:
137
138 gpio_pio_i: gpio-controller@14B0 {
139 #gpio-cells = <2>;
140 compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
141 reg = <0x1480 0x18>;
142 gpio-controller;
143 gpio-ranges = <&pinctrl1 0 20 10>,
144 <&pinctrl2 10 0 0>,
145 <&pinctrl1 15 0 10>,
146 <&pinctrl2 25 0 0>;
147 gpio-ranges-group-names = "",
148 "foo",
149 "",
150 "bar";
151 };
152
153Here, three GPIO ranges are defined wrt. two pin controllers. pinctrl1 GPIO
154ranges are defined using pin numbers whereas the GPIO ranges wrt. pinctrl2
155are named "foo" and "bar".
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 0dfaf20e4dad..e78760921bd7 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -190,10 +190,15 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
190 struct of_phandle_args pinspec; 190 struct of_phandle_args pinspec;
191 struct pinctrl_dev *pctldev; 191 struct pinctrl_dev *pctldev;
192 int index = 0, ret; 192 int index = 0, ret;
193 const char *name;
194 static const char group_names_propname[] = "gpio-ranges-group-names";
195 struct property *group_names;
193 196
194 if (!np) 197 if (!np)
195 return; 198 return;
196 199
200 group_names = of_find_property(np, group_names_propname, NULL);
201
197 for (;; index++) { 202 for (;; index++) {
198 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 203 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
199 index, &pinspec); 204 index, &pinspec);
@@ -204,14 +209,56 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
204 if (!pctldev) 209 if (!pctldev)
205 break; 210 break;
206 211
207 ret = gpiochip_add_pin_range(chip, 212 if (pinspec.args[2]) {
208 pinctrl_dev_get_devname(pctldev), 213 if (group_names) {
209 pinspec.args[0], 214 ret = of_property_read_string_index(np,
210 pinspec.args[1], 215 group_names_propname,
211 pinspec.args[2]); 216 index, &name);
212 217 if (strlen(name)) {
213 if (ret) 218 pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n",
214 break; 219 np->full_name);
220 break;
221 }
222 }
223 /* npins != 0: linear range */
224 ret = gpiochip_add_pin_range(chip,
225 pinctrl_dev_get_devname(pctldev),
226 pinspec.args[0],
227 pinspec.args[1],
228 pinspec.args[2]);
229 if (ret)
230 break;
231 } else {
232 /* npins == 0: special range */
233 if (pinspec.args[1]) {
234 pr_err("%s: Illegal gpio-range format.\n",
235 np->full_name);
236 break;
237 }
238
239 if (!group_names) {
240 pr_err("%s: GPIO group range requested but no %s property.\n",
241 np->full_name, group_names_propname);
242 break;
243 }
244
245 ret = of_property_read_string_index(np,
246 group_names_propname,
247 index, &name);
248 if (ret)
249 break;
250
251 if (!strlen(name)) {
252 pr_err("%s: Group name of GPIO group range cannot be the empty string.\n",
253 np->full_name);
254 break;
255 }
256
257 ret = gpiochip_add_pingroup_range(chip, pctldev,
258 pinspec.args[0], name);
259 if (ret)
260 break;
261 }
215 } 262 }
216} 263}
217 264
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 86ef3461ec06..b83b7e491f76 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1320,6 +1320,53 @@ EXPORT_SYMBOL_GPL(gpiochip_find);
1320#ifdef CONFIG_PINCTRL 1320#ifdef CONFIG_PINCTRL
1321 1321
1322/** 1322/**
1323 * gpiochip_add_pingroup_range() - add a range for GPIO <-> pin mapping
1324 * @chip: the gpiochip to add the range for
1325 * @pinctrl: the dev_name() of the pin controller to map to
1326 * @gpio_offset: the start offset in the current gpio_chip number space
1327 * @pin_group: name of the pin group inside the pin controller
1328 */
1329int gpiochip_add_pingroup_range(struct gpio_chip *chip,
1330 struct pinctrl_dev *pctldev,
1331 unsigned int gpio_offset, const char *pin_group)
1332{
1333 struct gpio_pin_range *pin_range;
1334 int ret;
1335
1336 pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL);
1337 if (!pin_range) {
1338 pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
1339 chip->label);
1340 return -ENOMEM;
1341 }
1342
1343 /* Use local offset as range ID */
1344 pin_range->range.id = gpio_offset;
1345 pin_range->range.gc = chip;
1346 pin_range->range.name = chip->label;
1347 pin_range->range.base = chip->base + gpio_offset;
1348 pin_range->pctldev = pctldev;
1349
1350 ret = pinctrl_get_group_pins(pctldev, pin_group,
1351 &pin_range->range.pins,
1352 &pin_range->range.npins);
1353 if (ret < 0)
1354 return ret;
1355
1356 pinctrl_add_gpio_range(pctldev, &pin_range->range);
1357
1358 pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PINGRP %s\n",
1359 chip->label, gpio_offset,
1360 gpio_offset + pin_range->range.npins - 1,
1361 pinctrl_dev_get_devname(pctldev), pin_group);
1362
1363 list_add_tail(&pin_range->node, &chip->pin_ranges);
1364
1365 return 0;
1366}
1367EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range);
1368
1369/**
1323 * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping 1370 * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping
1324 * @chip: the gpiochip to add the range for 1371 * @chip: the gpiochip to add the range for
1325 * @pinctrl_name: the dev_name() of the pin controller to map to 1372 * @pinctrl_name: the dev_name() of the pin controller to map to
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 92f86ab30a13..5ee61a470016 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -462,6 +462,20 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
462} 462}
463EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); 463EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);
464 464
465int pinctrl_get_group_pins(struct pinctrl_dev *pctldev, const char *pin_group,
466 const unsigned **pins, unsigned *num_pins)
467{
468 const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
469 int gs;
470
471 gs = pinctrl_get_group_selector(pctldev, pin_group);
472 if (gs < 0)
473 return gs;
474
475 return pctlops->get_group_pins(pctldev, gs, pins, num_pins);
476}
477EXPORT_SYMBOL_GPL(pinctrl_get_group_pins);
478
465/** 479/**
466 * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin 480 * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin
467 * @pctldev: the pin controller device to look in 481 * @pctldev: the pin controller device to look in
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index bde646995d10..523f40525535 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -228,6 +228,9 @@ struct gpio_pin_range {
228int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 228int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
229 unsigned int gpio_offset, unsigned int pin_offset, 229 unsigned int gpio_offset, unsigned int pin_offset,
230 unsigned int npins); 230 unsigned int npins);
231int gpiochip_add_pingroup_range(struct gpio_chip *chip,
232 struct pinctrl_dev *pctldev,
233 unsigned int gpio_offset, const char *pin_group);
231void gpiochip_remove_pin_ranges(struct gpio_chip *chip); 234void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
232 235
233#else 236#else
@@ -239,6 +242,13 @@ gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
239{ 242{
240 return 0; 243 return 0;
241} 244}
245static inline int
246gpiochip_add_pingroup_range(struct gpio_chip *chip,
247 struct pinctrl_dev *pctldev,
248 unsigned int gpio_offset, const char *pin_group)
249{
250 return 0;
251}
242 252
243static inline void 253static inline void
244gpiochip_remove_pin_ranges(struct gpio_chip *chip) 254gpiochip_remove_pin_ranges(struct gpio_chip *chip)
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 552e3f46e4a3..b8d0e53a802f 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -80,6 +80,7 @@ static inline int irq_to_gpio(unsigned int irq)
80#include <linux/types.h> 80#include <linux/types.h>
81#include <linux/errno.h> 81#include <linux/errno.h>
82#include <linux/bug.h> 82#include <linux/bug.h>
83#include <linux/pinctrl/pinctrl.h>
83 84
84struct device; 85struct device;
85struct gpio_chip; 86struct gpio_chip;
@@ -220,6 +221,15 @@ gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
220 return -EINVAL; 221 return -EINVAL;
221} 222}
222 223
224static inline int
225gpiochip_add_pingroup_range(struct gpio_chip *chip,
226 struct pinctrl_dev *pctldev,
227 unsigned int gpio_offset, const char *pin_group)
228{
229 WARN_ON(1);
230 return -EINVAL;
231}
232
223static inline void 233static inline void
224gpiochip_remove_pin_ranges(struct gpio_chip *chip) 234gpiochip_remove_pin_ranges(struct gpio_chip *chip)
225{ 235{
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 5979147d2bda..fefb88663975 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -144,6 +144,9 @@ extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname,
144extern struct pinctrl_gpio_range * 144extern struct pinctrl_gpio_range *
145pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, 145pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
146 unsigned int pin); 146 unsigned int pin);
147extern int pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
148 const char *pin_group, const unsigned **pins,
149 unsigned *num_pins);
147 150
148#ifdef CONFIG_OF 151#ifdef CONFIG_OF
149extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); 152extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np);