Commit 93ebe863 authored by Timur Tabi's avatar Timur Tabi Committed by Linus Walleij

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: default avatarTimur Tabi <timur@codeaurora.org>
Reviewed-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 1ca2a92b
...@@ -507,6 +507,11 @@ static void msm_gpio_dbg_show_one(struct seq_file *s, ...@@ -507,6 +507,11 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
}; };
g = &pctrl->soc->groups[offset]; g = &pctrl->soc->groups[offset];
/* If the GPIO group has no pins, then don't show it. */
if (!g->npins)
return;
ctl_reg = readl(pctrl->regs + g->ctl_reg); ctl_reg = readl(pctrl->regs + g->ctl_reg);
is_out = !!(ctl_reg & BIT(g->oe_bit)); is_out = !!(ctl_reg & BIT(g->oe_bit));
...@@ -516,7 +521,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s, ...@@ -516,7 +521,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,
seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func); seq_printf(s, " %-8s: %-3s %d", g->name, is_out ? "out" : "in", func);
seq_printf(s, " %dmA", msm_regval_to_drive(drive)); seq_printf(s, " %dmA", msm_regval_to_drive(drive));
seq_printf(s, " %s", pulls[pull]); seq_printf(s, " %s\n", pulls[pull]);
} }
static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 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,23 +529,36 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
unsigned gpio = chip->base; unsigned gpio = chip->base;
unsigned i; unsigned i;
for (i = 0; i < chip->ngpio; i++, gpio++) { for (i = 0; i < chip->ngpio; i++, gpio++)
msm_gpio_dbg_show_one(s, NULL, chip, i, gpio); msm_gpio_dbg_show_one(s, NULL, chip, i, gpio);
seq_puts(s, "\n");
}
} }
#else #else
#define msm_gpio_dbg_show NULL #define msm_gpio_dbg_show NULL
#endif #endif
/*
* If the requested GPIO has no pins, then treat it as unavailable.
* Otherwise, call the standard request function.
*/
static int msm_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
struct msm_pinctrl *pctrl = gpiochip_get_data(chip);
const struct msm_pingroup *g = &pctrl->soc->groups[offset];
if (!g->npins)
return -EACCES;
return gpiochip_generic_request(chip, offset);
}
static const struct gpio_chip msm_gpio_template = { static const struct gpio_chip msm_gpio_template = {
.direction_input = msm_gpio_direction_input, .direction_input = msm_gpio_direction_input,
.direction_output = msm_gpio_direction_output, .direction_output = msm_gpio_direction_output,
.get_direction = msm_gpio_get_direction, .get_direction = msm_gpio_get_direction,
.get = msm_gpio_get, .get = msm_gpio_get,
.set = msm_gpio_set, .set = msm_gpio_set,
.request = gpiochip_generic_request, .request = msm_gpio_request,
.free = gpiochip_generic_free, .free = gpiochip_generic_free,
.dbg_show = msm_gpio_dbg_show, .dbg_show = msm_gpio_dbg_show,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment