diff options
author | Timur Tabi <timur@codeaurora.org> | 2017-12-20 14:10:32 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2017-12-21 07:04:35 -0500 |
commit | 93ebe8636bb0d95e2e711f2a53abbb72a9d9cf8d (patch) | |
tree | 479035b14d57340c881bd7e0a2f0f26b09f3a367 | |
parent | 1ca2a92b2a99323f666f1b669b7484df4bda05e4 (diff) |
pinctrl: qcom: disable GPIO groups with no pins
pinctrl-msm only accepts an array of GPIOs from 0 to n-1, and it expects
each group to support have only one pin (npins == 1).
We can support "sparse" GPIO maps if we allow for some groups to have zero
pins (npins == 0). These pins are "hidden" from the rest of the driver
and gpiolib.
Access to unavailable GPIOs is blocked via a request callback. If the
requested GPIO is unavailable, -EACCES is returned, which prevents
further access to that GPIO.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/qcom/pinctrl-msm.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 7a960590ecaa..d45b4c2b5af1 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -507,6 +507,11 @@ static void msm_gpio_dbg_show_one(struct seq_file *s, | |||
507 | }; | 507 | }; |
508 | 508 | ||
509 | g = &pctrl->soc->groups[offset]; | 509 | g = &pctrl->soc->groups[offset]; |
510 | |||
511 | /* If the GPIO group has no pins, then don't show it. */ | ||
512 | if (!g->npins) | ||
513 | return; | ||
514 | |||
510 | ctl_reg = readl(pctrl->regs + g->ctl_reg); | 515 | ctl_reg = readl(pctrl->regs + g->ctl_reg); |
511 | 516 | ||
512 | is_out = !!(ctl_reg & BIT(g->oe_bit)); | 517 | is_out = !!(ctl_reg & BIT(g->oe_bit)); |
@@ -516,7 +521,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s, | |||
516 | 521 | ||
517 | seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func); | 522 | seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func); |
518 | seq_printf(s, " %dmA", msm_regval_to_drive(drive)); | 523 | seq_printf(s, " %dmA", msm_regval_to_drive(drive)); |
519 | seq_printf(s, " %s", pulls[pull]); | 524 | seq_printf(s, " %s\n", pulls[pull]); |
520 | } | 525 | } |
521 | 526 | ||
522 | static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 527 | static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
@@ -524,23 +529,36 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
524 | unsigned gpio = chip->base; | 529 | unsigned gpio = chip->base; |
525 | unsigned i; | 530 | unsigned i; |
526 | 531 | ||
527 | for (i = 0; i < chip->ngpio; i++, gpio++) { | 532 | for (i = 0; i < chip->ngpio; i++, gpio++) |
528 | msm_gpio_dbg_show_one(s, NULL, chip, i, gpio); | 533 | msm_gpio_dbg_show_one(s, NULL, chip, i, gpio); |
529 | seq_puts(s, "\n"); | ||
530 | } | ||
531 | } | 534 | } |
532 | 535 | ||
533 | #else | 536 | #else |
534 | #define msm_gpio_dbg_show NULL | 537 | #define msm_gpio_dbg_show NULL |
535 | #endif | 538 | #endif |
536 | 539 | ||
540 | /* | ||
541 | * If the requested GPIO has no pins, then treat it as unavailable. | ||
542 | * Otherwise, call the standard request function. | ||
543 | */ | ||
544 | static int msm_gpio_request(struct gpio_chip *chip, unsigned int offset) | ||
545 | { | ||
546 | struct msm_pinctrl *pctrl = gpiochip_get_data(chip); | ||
547 | const struct msm_pingroup *g = &pctrl->soc->groups[offset]; | ||
548 | |||
549 | if (!g->npins) | ||
550 | return -EACCES; | ||
551 | |||
552 | return gpiochip_generic_request(chip, offset); | ||
553 | } | ||
554 | |||
537 | static const struct gpio_chip msm_gpio_template = { | 555 | static const struct gpio_chip msm_gpio_template = { |
538 | .direction_input = msm_gpio_direction_input, | 556 | .direction_input = msm_gpio_direction_input, |
539 | .direction_output = msm_gpio_direction_output, | 557 | .direction_output = msm_gpio_direction_output, |
540 | .get_direction = msm_gpio_get_direction, | 558 | .get_direction = msm_gpio_get_direction, |
541 | .get = msm_gpio_get, | 559 | .get = msm_gpio_get, |
542 | .set = msm_gpio_set, | 560 | .set = msm_gpio_set, |
543 | .request = gpiochip_generic_request, | 561 | .request = msm_gpio_request, |
544 | .free = gpiochip_generic_free, | 562 | .free = gpiochip_generic_free, |
545 | .dbg_show = msm_gpio_dbg_show, | 563 | .dbg_show = msm_gpio_dbg_show, |
546 | }; | 564 | }; |