aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/core.c59
1 files changed, 49 insertions, 10 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);