diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-at91.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-at91.c | 189 |
1 files changed, 90 insertions, 99 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 735c501e7a06..871209c24153 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/seq_file.h> #include <linux/slab.h> +#include <linux/string_helpers.h> /* Since we request GPIOs from ourself */ #include <linux/pinctrl/consumer.h> @@ -41,7 +42,6 @@ struct at91_pinctrl_mux_ops; * @next: bank sharing same clock * @pioc_hwirq: PIO bank interrupt identifier on AIC * @pioc_virq: PIO bank Linux virtual interrupt - * @pioc_idx: PIO bank index * @regbase: PIO bank virtual address * @clock: associated clock * @ops: at91 pinctrl mux ops @@ -55,7 +55,6 @@ struct at91_gpio_chip { struct at91_gpio_chip *next; int pioc_hwirq; int pioc_virq; - int pioc_idx; void __iomem *regbase; struct clk *clock; const struct at91_pinctrl_mux_ops *ops; @@ -1293,18 +1292,18 @@ static const struct of_device_id at91_pinctrl_of_match[] = { static int at91_pinctrl_probe_dt(struct platform_device *pdev, struct at91_pinctrl *info) { + struct device *dev = &pdev->dev; int ret = 0; int i, j, ngpio_chips_enabled = 0; uint32_t *tmp; - struct device_node *np = pdev->dev.of_node; + struct device_node *np = dev->of_node; struct device_node *child; if (!np) return -ENODEV; - info->dev = &pdev->dev; - info->ops = (const struct at91_pinctrl_mux_ops *) - of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; + info->dev = dev; + info->ops = of_device_get_match_data(dev); at91_pinctrl_child_count(info, np); /* @@ -1323,35 +1322,31 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, if (ret) return ret; - dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux); + dev_dbg(dev, "nmux = %d\n", info->nmux); - dev_dbg(&pdev->dev, "mux-mask\n"); + dev_dbg(dev, "mux-mask\n"); tmp = info->mux_mask; 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]); + dev_dbg(dev, "%d:%d\t0x%x\n", i, j, tmp[0]); } } - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); - info->functions = devm_kcalloc(&pdev->dev, - info->nfunctions, - sizeof(struct at91_pmx_func), - GFP_KERNEL); + dev_dbg(dev, "nfunctions = %d\n", info->nfunctions); + dev_dbg(dev, "ngroups = %d\n", info->ngroups); + info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), + GFP_KERNEL); if (!info->functions) return -ENOMEM; - info->groups = devm_kcalloc(&pdev->dev, - info->ngroups, - sizeof(struct at91_pin_group), - GFP_KERNEL); + info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), + GFP_KERNEL); if (!info->groups) return -ENOMEM; - 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); + dev_dbg(dev, "nbanks = %d\n", gpio_banks); + dev_dbg(dev, "nfunctions = %d\n", info->nfunctions); + dev_dbg(dev, "ngroups = %d\n", info->ngroups); i = 0; @@ -1360,9 +1355,8 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, continue; ret = at91_pinctrl_parse_functions(child, info, i++); if (ret) { - dev_err(&pdev->dev, "failed to parse function\n"); of_node_put(child); - return ret; + return dev_err_probe(dev, ret, "failed to parse function\n"); } } @@ -1371,11 +1365,12 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, static int at91_pinctrl_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct at91_pinctrl *info; struct pinctrl_pin_desc *pdesc; int ret, i, j, k; - info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -1383,39 +1378,42 @@ static int at91_pinctrl_probe(struct platform_device *pdev) if (ret) return ret; - at91_pinctrl_desc.name = dev_name(&pdev->dev); + at91_pinctrl_desc.name = dev_name(dev); at91_pinctrl_desc.npins = gpio_banks * MAX_NB_GPIO_PER_BANK; at91_pinctrl_desc.pins = pdesc = - devm_kcalloc(&pdev->dev, - at91_pinctrl_desc.npins, sizeof(*pdesc), - GFP_KERNEL); - + devm_kcalloc(dev, at91_pinctrl_desc.npins, sizeof(*pdesc), GFP_KERNEL); if (!at91_pinctrl_desc.pins) return -ENOMEM; for (i = 0, k = 0; i < gpio_banks; i++) { + char **names; + + names = devm_kasprintf_strarray(dev, "pio", MAX_NB_GPIO_PER_BANK); + if (!names) + return -ENOMEM; + for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { + char *name = names[j]; + + strreplace(name, '-', i + 'A'); + pdesc->number = k; - pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); + pdesc->name = name; pdesc++; } } platform_set_drvdata(pdev, info); - info->pctl = devm_pinctrl_register(&pdev->dev, &at91_pinctrl_desc, - info); - - if (IS_ERR(info->pctl)) { - dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); - return PTR_ERR(info->pctl); - } + info->pctl = devm_pinctrl_register(dev, &at91_pinctrl_desc, info); + if (IS_ERR(info->pctl)) + return dev_err_probe(dev, PTR_ERR(info->pctl), "could not register AT91 pinctrl driver\n"); /* We will handle a range of GPIO pins */ 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"); + dev_info(dev, "initialized AT91 pinctrl driver\n"); return 0; } @@ -1526,6 +1524,20 @@ static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) #define at91_gpio_dbg_show NULL #endif +static int gpio_irq_request_resources(struct irq_data *d) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + + return gpiochip_lock_as_irq(&at91_gpio->chip, irqd_to_hwirq(d)); +} + +static void gpio_irq_release_resources(struct irq_data *d) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + + gpiochip_unlock_as_irq(&at91_gpio->chip, irqd_to_hwirq(d)); +} + /* Several AIC controller irqs are dispatched through this GPIO handler. * To use any AT91_PIN_* as an externally triggered IRQ, first call * at91_set_gpio_input() then maybe enable its glitch filter. @@ -1545,6 +1557,9 @@ static void gpio_irq_mask(struct irq_data *d) struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); void __iomem *pio = at91_gpio->regbase; unsigned mask = 1 << d->hwirq; + unsigned gpio = irqd_to_hwirq(d); + + gpiochip_disable_irq(&at91_gpio->chip, gpio); if (pio) writel_relaxed(mask, pio + PIO_IDR); @@ -1555,6 +1570,9 @@ static void gpio_irq_unmask(struct irq_data *d) struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); void __iomem *pio = at91_gpio->regbase; unsigned mask = 1 << d->hwirq; + unsigned gpio = irqd_to_hwirq(d); + + gpiochip_enable_irq(&at91_gpio->chip, gpio); if (pio) writel_relaxed(mask, pio + PIO_IER); @@ -1706,6 +1724,7 @@ static void gpio_irq_handler(struct irq_desc *desc) static int at91_gpio_of_irq_setup(struct platform_device *pdev, struct at91_gpio_chip *at91_gpio) { + struct device *dev = &pdev->dev; struct gpio_chip *gpiochip_prev = NULL; struct at91_gpio_chip *prev = NULL; struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); @@ -1713,20 +1732,22 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev, struct gpio_irq_chip *girq; int i; - gpio_irqchip = devm_kzalloc(&pdev->dev, sizeof(*gpio_irqchip), - GFP_KERNEL); + gpio_irqchip = devm_kzalloc(dev, sizeof(*gpio_irqchip), GFP_KERNEL); if (!gpio_irqchip) return -ENOMEM; at91_gpio->pioc_hwirq = irqd_to_hwirq(d); gpio_irqchip->name = "GPIO"; + gpio_irqchip->irq_request_resources = gpio_irq_request_resources; + gpio_irqchip->irq_release_resources = gpio_irq_release_resources; gpio_irqchip->irq_ack = gpio_irq_ack; gpio_irqchip->irq_disable = gpio_irq_mask; gpio_irqchip->irq_mask = gpio_irq_mask; gpio_irqchip->irq_unmask = gpio_irq_unmask; gpio_irqchip->irq_set_wake = pm_ptr(gpio_irq_set_wake); gpio_irqchip->irq_set_type = at91_gpio->ops->irq_type; + gpio_irqchip->flags = IRQCHIP_IMMUTABLE; /* Disable irqs of this PIO controller */ writel_relaxed(~0, at91_gpio->regbase + PIO_IDR); @@ -1737,7 +1758,7 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev, * interrupt. */ girq = &at91_gpio->chip.irq; - girq->chip = gpio_irqchip; + gpio_irq_chip_set_chip(girq, gpio_irqchip); girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_edge_irq; @@ -1750,7 +1771,7 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev, if (!gpiochip_prev) { girq->parent_handler = gpio_irq_handler; girq->num_parents = 1; - girq->parents = devm_kcalloc(&pdev->dev, 1, + girq->parents = devm_kcalloc(dev, girq->num_parents, sizeof(*girq->parents), GFP_KERNEL); if (!girq->parents) @@ -1797,7 +1818,8 @@ static const struct of_device_id at91_gpio_of_match[] = { static int at91_gpio_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct at91_gpio_chip *at91_chip = NULL; struct gpio_chip *chip; struct pinctrl_gpio_range *range; @@ -1808,74 +1830,51 @@ static int at91_gpio_probe(struct platform_device *pdev) char **names; BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); - if (gpio_chips[alias_idx]) { - ret = -EBUSY; - goto err; - } + if (gpio_chips[alias_idx]) + return dev_err_probe(dev, -EBUSY, "%d slot is occupied.\n", alias_idx); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto err; - } + if (irq < 0) + return irq; - at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL); - if (!at91_chip) { - ret = -ENOMEM; - goto err; - } + at91_chip = devm_kzalloc(dev, sizeof(*at91_chip), GFP_KERNEL); + if (!at91_chip) + return -ENOMEM; at91_chip->regbase = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(at91_chip->regbase)) { - ret = PTR_ERR(at91_chip->regbase); - goto err; - } + if (IS_ERR(at91_chip->regbase)) + return PTR_ERR(at91_chip->regbase); - at91_chip->ops = (const struct at91_pinctrl_mux_ops *) - of_match_device(at91_gpio_of_match, &pdev->dev)->data; + at91_chip->ops = of_device_get_match_data(dev); at91_chip->pioc_virq = irq; - at91_chip->pioc_idx = alias_idx; - at91_chip->clock = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(at91_chip->clock)) { - dev_err(&pdev->dev, "failed to get clock, ignoring.\n"); - ret = PTR_ERR(at91_chip->clock); - goto err; - } - - ret = clk_prepare_enable(at91_chip->clock); - if (ret) { - dev_err(&pdev->dev, "failed to prepare and enable clock, ignoring.\n"); - goto clk_enable_err; - } + at91_chip->clock = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(at91_chip->clock)) + return dev_err_probe(dev, PTR_ERR(at91_chip->clock), "failed to get clock, ignoring.\n"); at91_chip->chip = at91_gpio_template; at91_chip->id = alias_idx; chip = &at91_chip->chip; - chip->label = dev_name(&pdev->dev); - chip->parent = &pdev->dev; + chip->label = dev_name(dev); + chip->parent = dev; chip->owner = THIS_MODULE; chip->base = alias_idx * MAX_NB_GPIO_PER_BANK; if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { if (ngpio >= MAX_NB_GPIO_PER_BANK) - pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", - alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); + dev_err(dev, "at91_gpio.%d, gpio-nb >= %d failback to %d\n", + alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); else chip->ngpio = ngpio; } - names = devm_kcalloc(&pdev->dev, chip->ngpio, sizeof(char *), - GFP_KERNEL); - - if (!names) { - ret = -ENOMEM; - goto clk_enable_err; - } + names = devm_kasprintf_strarray(dev, "pio", chip->ngpio); + if (!names) + return -ENOMEM; for (i = 0; i < chip->ngpio; i++) - names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); + strreplace(names[i], '-', alias_idx + 'A'); chip->names = (const char *const *)names; @@ -1889,27 +1888,19 @@ static int at91_gpio_probe(struct platform_device *pdev) ret = at91_gpio_of_irq_setup(pdev, at91_chip); if (ret) - goto gpiochip_add_err; + return ret; ret = gpiochip_add_data(chip, at91_chip); if (ret) - goto gpiochip_add_err; + return ret; gpio_chips[alias_idx] = at91_chip; platform_set_drvdata(pdev, at91_chip); gpio_banks = max(gpio_banks, alias_idx + 1); - dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase); + dev_info(dev, "at address %p\n", at91_chip->regbase); return 0; - -gpiochip_add_err: -clk_enable_err: - clk_disable_unprepare(at91_chip->clock); -err: - dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx); - - return ret; } static const struct dev_pm_ops at91_gpio_pm_ops = { |