aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ruppert <christian.ruppert@abilis.com>2013-06-13 08:55:31 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-17 12:18:28 -0400
commitc8587eeef8fc219e806e868c6f0c7170c769efab (patch)
treee97d8c30c967cf08b8b92d4653acebe52f942ca8
parent5ace03fb6abfa3b316c7ee6a105959cb45bd4af4 (diff)
pinctrl: add pin list based GPIO ranges
Traditionally, GPIO ranges are based on consecutive ranges of both GPIO and pin numbers. This patch allows for GPIO ranges with arbitrary lists of pin numbers. Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/core.c59
-rw-r--r--include/linux/pinctrl/pinctrl.h4
2 files changed, 52 insertions, 11 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index dca9208f5463..33710b5e7bb5 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -283,6 +283,29 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev,
283} 283}
284 284
285/** 285/**
286 * gpio_to_pin() - GPIO range GPIO number to pin number translation
287 * @range: GPIO range used for the translation
288 * @gpio: gpio pin to translate to a pin number
289 *
290 * Finds the pin number for a given GPIO using the specified GPIO range
291 * as a base for translation. The distinction between linear GPIO ranges
292 * and pin list based GPIO ranges is managed correctly by this function.
293 *
294 * This function assumes the gpio is part of the specified GPIO range, use
295 * only after making sure this is the case (e.g. by calling it on the
296 * result of successful pinctrl_get_device_gpio_range calls)!
297 */
298static inline int gpio_to_pin(struct pinctrl_gpio_range *range,
299 unsigned int gpio)
300{
301 unsigned int offset = gpio - range->base;
302 if (range->pins)
303 return range->pins[offset];
304 else
305 return range->pin_base + offset;
306}
307
308/**
286 * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range 309 * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range
287 * @pctldev: pin controller device to check 310 * @pctldev: pin controller device to check
288 * @gpio: gpio pin to check taken from the global GPIO pin space 311 * @gpio: gpio pin to check taken from the global GPIO pin space
@@ -448,8 +471,14 @@ pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
448 /* Loop over the ranges */ 471 /* Loop over the ranges */
449 list_for_each_entry(range, &pctldev->gpio_ranges, node) { 472 list_for_each_entry(range, &pctldev->gpio_ranges, node) {
450 /* Check if we're in the valid range */ 473 /* Check if we're in the valid range */
451 if (pin >= range->pin_base && 474 if (range->pins) {
452 pin < range->pin_base + range->npins) { 475 int a;
476 for (a = 0; a < range->npins; a++) {
477 if (range->pins[a] == pin)
478 return range;
479 }
480 } else if (pin >= range->pin_base &&
481 pin < range->pin_base + range->npins) {
453 mutex_unlock(&pctldev->mutex); 482 mutex_unlock(&pctldev->mutex);
454 return range; 483 return range;
455 } 484 }
@@ -529,7 +558,7 @@ int pinctrl_request_gpio(unsigned gpio)
529 } 558 }
530 559
531 /* Convert to the pin controllers number space */ 560 /* Convert to the pin controllers number space */
532 pin = gpio - range->base + range->pin_base; 561 pin = gpio_to_pin(range, gpio);
533 562
534 ret = pinmux_request_gpio(pctldev, range, pin, gpio); 563 ret = pinmux_request_gpio(pctldev, range, pin, gpio);
535 564
@@ -559,7 +588,7 @@ void pinctrl_free_gpio(unsigned gpio)
559 mutex_lock(&pctldev->mutex); 588 mutex_lock(&pctldev->mutex);
560 589
561 /* Convert to the pin controllers number space */ 590 /* Convert to the pin controllers number space */
562 pin = gpio - range->base + range->pin_base; 591 pin = gpio_to_pin(range, gpio);
563 592
564 pinmux_free_gpio(pctldev, pin, range); 593 pinmux_free_gpio(pctldev, pin, range);
565 594
@@ -582,7 +611,7 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input)
582 mutex_lock(&pctldev->mutex); 611 mutex_lock(&pctldev->mutex);
583 612
584 /* Convert to the pin controllers number space */ 613 /* Convert to the pin controllers number space */
585 pin = gpio - range->base + range->pin_base; 614 pin = gpio_to_pin(range, gpio);
586 ret = pinmux_gpio_direction(pctldev, range, pin, input); 615 ret = pinmux_gpio_direction(pctldev, range, pin, input);
587 616
588 mutex_unlock(&pctldev->mutex); 617 mutex_unlock(&pctldev->mutex);
@@ -1349,11 +1378,21 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
1349 1378
1350 /* Loop over the ranges */ 1379 /* Loop over the ranges */
1351 list_for_each_entry(range, &pctldev->gpio_ranges, node) { 1380 list_for_each_entry(range, &pctldev->gpio_ranges, node) {
1352 seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", 1381 if (range->pins) {
1353 range->id, range->name, 1382 int a;
1354 range->base, (range->base + range->npins - 1), 1383 seq_printf(s, "%u: %s GPIOS [%u - %u] PINS {",
1355 range->pin_base, 1384 range->id, range->name,
1356 (range->pin_base + range->npins - 1)); 1385 range->base, (range->base + range->npins - 1));
1386 for (a = 0; a < range->npins - 1; a++)
1387 seq_printf(s, "%u, ", range->pins[a]);
1388 seq_printf(s, "%u}\n", range->pins[a]);
1389 }
1390 else
1391 seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
1392 range->id, range->name,
1393 range->base, (range->base + range->npins - 1),
1394 range->pin_base,
1395 (range->pin_base + range->npins - 1));
1357 } 1396 }
1358 1397
1359 mutex_unlock(&pctldev->mutex); 1398 mutex_unlock(&pctldev->mutex);
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 2c2a9e8d8578..176a6c1b4e03 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -49,7 +49,8 @@ struct pinctrl_pin_desc {
49 * @name: a name for the chip in this range 49 * @name: a name for the chip in this range
50 * @id: an ID number for the chip in this range 50 * @id: an ID number for the chip in this range
51 * @base: base offset of the GPIO range 51 * @base: base offset of the GPIO range
52 * @pin_base: base pin number of the GPIO range 52 * @pin_base: base pin number of the GPIO range if pins != NULL
53 * @pins: enumeration of pins in GPIO range or NULL
53 * @npins: number of pins in the GPIO range, including the base number 54 * @npins: number of pins in the GPIO range, including the base number
54 * @gc: an optional pointer to a gpio_chip 55 * @gc: an optional pointer to a gpio_chip
55 */ 56 */
@@ -59,6 +60,7 @@ struct pinctrl_gpio_range {
59 unsigned int id; 60 unsigned int id;
60 unsigned int base; 61 unsigned int base;
61 unsigned int pin_base; 62 unsigned int pin_base;
63 unsigned const *pins;
62 unsigned int npins; 64 unsigned int npins;
63 struct gpio_chip *gc; 65 struct gpio_chip *gc;
64}; 66};