[PATCH v3 1/3] pinctrl: at91: allow to have disabled gpio bank
Nicolas Ferre
nicolas.ferre at atmel.com
Mon Jan 19 02:40:59 PST 2015
Le 16/01/2015 16:31, Ludovic Desroches a écrit :
> From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
>
> Today we expect that all the bank are enabled, and count the number of banks
> used by the pinctrl based on it instead of using the last bank id enabled.
>
> So switch to it, set the chained IRQ at runtime based on enabled banks
> and wait only the number of enabled gpio controllers at probe time.
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
>
> Cc: <stable at vger.kernel.org> # 3.18
As I acknowledged a comparable solution previously, and after reading,
this patch seems okay:
Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
Thanks, bye.
> ---
> drivers/pinctrl/pinctrl-at91.c | 108 +++++++++++++++++++++--------------------
> 1 file changed, 55 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index dfd021e..f4cd0b9 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -177,7 +177,7 @@ struct at91_pinctrl {
> struct device *dev;
> struct pinctrl_dev *pctl;
>
> - int nbanks;
> + int nactive_banks;
>
> uint32_t *mux_mask;
> int nmux;
> @@ -653,12 +653,18 @@ static int pin_check_config(struct at91_pinctrl *info, const char *name,
> int mux;
>
> /* check if it's a valid config */
> - if (pin->bank >= info->nbanks) {
> + if (pin->bank >= gpio_banks) {
> dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n",
> - name, index, pin->bank, info->nbanks);
> + name, index, pin->bank, gpio_banks);
> return -EINVAL;
> }
>
> + if (!gpio_chips[pin->bank]) {
> + dev_err(info->dev, "%s: pin conf %d bank_id %d not enabled\n",
> + name, index, pin->bank);
> + return -ENXIO;
> + }
> +
> if (pin->pin >= MAX_NB_GPIO_PER_BANK) {
> dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n",
> name, index, pin->pin, MAX_NB_GPIO_PER_BANK);
> @@ -981,7 +987,8 @@ static void at91_pinctrl_child_count(struct at91_pinctrl *info,
>
> for_each_child_of_node(np, child) {
> if (of_device_is_compatible(child, gpio_compat)) {
> - info->nbanks++;
> + if (of_device_is_available(child))
> + info->nactive_banks++;
> } else {
> info->nfunctions++;
> info->ngroups += of_get_child_count(child);
> @@ -1003,11 +1010,11 @@ static int at91_pinctrl_mux_mask(struct at91_pinctrl *info,
> }
>
> size /= sizeof(*list);
> - if (!size || size % info->nbanks) {
> - dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks);
> + if (!size || size % gpio_banks) {
> + dev_err(info->dev, "wrong mux mask array should be by %d\n", gpio_banks);
> return -EINVAL;
> }
> - info->nmux = size / info->nbanks;
> + info->nmux = size / gpio_banks;
>
> info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL);
> if (!info->mux_mask) {
> @@ -1131,7 +1138,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
> of_match_device(at91_pinctrl_of_match, &pdev->dev)->data;
> at91_pinctrl_child_count(info, np);
>
> - if (info->nbanks < 1) {
> + if (gpio_banks < 1) {
> dev_err(&pdev->dev, "you need to specify at least one gpio-controller\n");
> return -EINVAL;
> }
> @@ -1144,7 +1151,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
>
> dev_dbg(&pdev->dev, "mux-mask\n");
> tmp = info->mux_mask;
> - for (i = 0; i < info->nbanks; i++) {
> + for (i = 0; i < gpio_banks; i++) {
> for (j = 0; j < info->nmux; j++, tmp++) {
> dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]);
> }
> @@ -1162,7 +1169,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev,
> if (!info->groups)
> return -ENOMEM;
>
> - dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks);
> + dev_dbg(&pdev->dev, "nbanks = %d\n", gpio_banks);
> dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
> dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
>
> @@ -1185,7 +1192,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
> {
> struct at91_pinctrl *info;
> struct pinctrl_pin_desc *pdesc;
> - int ret, i, j, k;
> + int ret, i, j, k, ngpio_chips_enabled = 0;
>
> info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> if (!info)
> @@ -1200,23 +1207,27 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
> * to obtain references to the struct gpio_chip * for them, and we
> * need this to proceed.
> */
> - for (i = 0; i < info->nbanks; i++) {
> - if (!gpio_chips[i]) {
> - dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
> - devm_kfree(&pdev->dev, info);
> - return -EPROBE_DEFER;
> - }
> + for (i = 0; i < gpio_banks; i++)
> + if (gpio_chips[i])
> + ngpio_chips_enabled++;
> +
> + if (ngpio_chips_enabled < info->nactive_banks) {
> + dev_warn(&pdev->dev,
> + "All GPIO chips are not registered yet (%d/%d)\n",
> + ngpio_chips_enabled, info->nactive_banks);
> + devm_kfree(&pdev->dev, info);
> + return -EPROBE_DEFER;
> }
>
> at91_pinctrl_desc.name = dev_name(&pdev->dev);
> - at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK;
> + at91_pinctrl_desc.npins = gpio_banks * MAX_NB_GPIO_PER_BANK;
> at91_pinctrl_desc.pins = pdesc =
> devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL);
>
> if (!at91_pinctrl_desc.pins)
> return -ENOMEM;
>
> - for (i = 0 , k = 0; i < info->nbanks; i++) {
> + for (i = 0, k = 0; i < gpio_banks; i++) {
> for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) {
> pdesc->number = k;
> pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j);
> @@ -1234,8 +1245,9 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
> }
>
> /* We will handle a range of GPIO pins */
> - for (i = 0; i < info->nbanks; i++)
> - pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range);
> + for (i = 0; i < gpio_banks; i++)
> + if (gpio_chips[i])
> + pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range);
>
> dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n");
>
> @@ -1613,9 +1625,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
> static int at91_gpio_of_irq_setup(struct platform_device *pdev,
> struct at91_gpio_chip *at91_gpio)
> {
> + struct gpio_chip *gpiochip_prev = NULL;
> struct at91_gpio_chip *prev = NULL;
> struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq);
> - int ret;
> + int ret, i;
>
> at91_gpio->pioc_hwirq = irqd_to_hwirq(d);
>
> @@ -1641,24 +1654,33 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev,
> return ret;
> }
>
> - /* Setup chained handler */
> - if (at91_gpio->pioc_idx)
> - prev = gpio_chips[at91_gpio->pioc_idx - 1];
> -
> /* The top level handler handles one bank of GPIOs, except
> * on some SoC it can handle up to three...
> * We only set up the handler for the first of the list.
> */
> - if (prev && prev->next == at91_gpio)
> + gpiochip_prev = irq_get_handler_data(at91_gpio->pioc_virq);
> + if (!gpiochip_prev) {
> + /* Then register the chain on the parent IRQ */
> + gpiochip_set_chained_irqchip(&at91_gpio->chip,
> + &gpio_irqchip,
> + at91_gpio->pioc_virq,
> + gpio_irq_handler);
> return 0;
> + }
>
> - /* Then register the chain on the parent IRQ */
> - gpiochip_set_chained_irqchip(&at91_gpio->chip,
> - &gpio_irqchip,
> - at91_gpio->pioc_virq,
> - gpio_irq_handler);
> + prev = container_of(gpiochip_prev, struct at91_gpio_chip, chip);
>
> - return 0;
> + /* we can only have 2 banks before */
> + for (i = 0; i < 2; i++) {
> + if (prev->next) {
> + prev = prev->next;
> + } else {
> + prev->next = at91_gpio;
> + return 0;
> + }
> + }
> +
> + return -EINVAL;
> }
>
> /* This structure is replicated for each GPIO block allocated at probe time */
> @@ -1675,24 +1697,6 @@ static struct gpio_chip at91_gpio_template = {
> .ngpio = MAX_NB_GPIO_PER_BANK,
> };
>
> -static void at91_gpio_probe_fixup(void)
> -{
> - unsigned i;
> - struct at91_gpio_chip *at91_gpio, *last = NULL;
> -
> - for (i = 0; i < gpio_banks; i++) {
> - at91_gpio = gpio_chips[i];
> -
> - /*
> - * GPIO controller are grouped on some SoC:
> - * PIOC, PIOD and PIOE can share the same IRQ line
> - */
> - if (last && last->pioc_virq == at91_gpio->pioc_virq)
> - last->next = at91_gpio;
> - last = at91_gpio;
> - }
> -}
> -
> static struct of_device_id at91_gpio_of_match[] = {
> { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, },
> { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops },
> @@ -1805,8 +1809,6 @@ static int at91_gpio_probe(struct platform_device *pdev)
> gpio_chips[alias_idx] = at91_chip;
> gpio_banks = max(gpio_banks, alias_idx + 1);
>
> - at91_gpio_probe_fixup();
> -
> ret = at91_gpio_of_irq_setup(pdev, at91_chip);
> if (ret)
> goto irq_setup_err;
>
--
Nicolas Ferre
More information about the linux-arm-kernel
mailing list