summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinctrl-at91.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-at91.c')
-rw-r--r--drivers/pinctrl/pinctrl-at91.c385
1 files changed, 184 insertions, 201 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index d91a010e65f5..0a57ed51d4c9 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -7,23 +7,24 @@
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/gpio/driver.h>
#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/io.h>
-#include <linux/gpio/driver.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/property.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>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
-/* Since we request GPIOs from ourself */
-#include <linux/pinctrl/consumer.h>
-
-#include <soc/at91/pm.h>
#include "pinctrl-at91.h"
#include "core.h"
@@ -33,16 +34,32 @@
struct at91_pinctrl_mux_ops;
+/**
+ * struct at91_gpio_chip: at91 gpio chip
+ * @chip: gpio chip
+ * @range: gpio range
+ * @next: bank sharing same clock
+ * @pioc_hwirq: PIO bank interrupt identifier on AIC
+ * @pioc_virq: PIO bank Linux virtual interrupt
+ * @regbase: PIO bank virtual address
+ * @clock: associated clock
+ * @ops: at91 pinctrl mux ops
+ * @wakeups: wakeup interrupts
+ * @backups: interrupts disabled in suspend
+ * @id: gpio chip identifier
+ */
struct at91_gpio_chip {
struct gpio_chip chip;
struct pinctrl_gpio_range range;
- struct at91_gpio_chip *next; /* Bank sharing same clock */
- int pioc_hwirq; /* PIO bank interrupt identifier on AIC */
- int pioc_virq; /* PIO bank Linux virtual interrupt */
- int pioc_idx; /* PIO bank index */
- void __iomem *regbase; /* PIO bank virtual address */
- struct clk *clock; /* associated clock */
- const struct at91_pinctrl_mux_ops *ops; /* ops */
+ struct at91_gpio_chip *next;
+ int pioc_hwirq;
+ int pioc_virq;
+ void __iomem *regbase;
+ struct clk *clock;
+ const struct at91_pinctrl_mux_ops *ops;
+ u32 wakeups;
+ u32 backups;
+ u32 id;
};
static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS];
@@ -1227,7 +1244,6 @@ static int at91_pinctrl_parse_groups(struct device_node *np,
static int at91_pinctrl_parse_functions(struct device_node *np,
struct at91_pinctrl *info, u32 index)
{
- struct device_node *child;
struct at91_pmx_func *func;
struct at91_pin_group *grp;
int ret;
@@ -1250,14 +1266,12 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
if (!func->groups)
return -ENOMEM;
- for_each_child_of_node(np, child) {
+ for_each_child_of_node_scoped(np, child) {
func->groups[i] = child->name;
grp = &info->groups[grp_index++];
ret = at91_pinctrl_parse_groups(child, grp, info, i++);
- if (ret) {
- of_node_put(child);
+ if (ret)
return ret;
- }
}
return 0;
@@ -1274,70 +1288,69 @@ 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;
+ int i, j, ngpio_chips_enabled = 0;
uint32_t *tmp;
- struct device_node *np = pdev->dev.of_node;
- struct device_node *child;
+ struct device_node *np = dev->of_node;
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->ops = device_get_match_data(&pdev->dev);
at91_pinctrl_child_count(info, np);
- if (gpio_banks < 1) {
- dev_err(&pdev->dev, "you need to specify at least one gpio-controller\n");
- return -EINVAL;
- }
+ /*
+ * We need all the GPIO drivers to probe FIRST, or we will not be able
+ * to obtain references to the struct gpio_chip * for them, and we
+ * need this to proceed.
+ */
+ for (i = 0; i < MAX_GPIO_BANKS; i++)
+ if (gpio_chips[i])
+ ngpio_chips_enabled++;
+
+ if (ngpio_chips_enabled < info->nactive_banks)
+ return -EPROBE_DEFER;
ret = at91_pinctrl_mux_mask(info, np);
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;
- for_each_child_of_node(np, child) {
+ for_each_child_of_node_scoped(np, child) {
if (of_device_is_compatible(child, gpio_compat))
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;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to parse function\n");
}
return 0;
@@ -1345,11 +1358,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, ngpio_chips_enabled = 0;
+ 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;
@@ -1357,56 +1371,45 @@ static int at91_pinctrl_probe(struct platform_device *pdev)
if (ret)
return ret;
- /*
- * We need all the GPIO drivers to probe FIRST, or we will not be able
- * to obtain references to the struct gpio_chip * for them, and we
- * need this to proceed.
- */
- 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.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 (IS_ERR(names))
+ return PTR_ERR(names);
+
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])
+ if (gpio_chips[i]) {
pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range);
+ gpiochip_add_pin_range(&gpio_chips[i]->chip, dev_name(info->pctl->dev), 0,
+ gpio_chips[i]->range.pin_base, gpio_chips[i]->range.npins);
+ }
- dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n");
+ dev_info(dev, "initialized AT91 pinctrl driver\n");
return 0;
}
@@ -1446,18 +1449,19 @@ static int at91_gpio_get(struct gpio_chip *chip, unsigned offset)
return (pdsr & mask) != 0;
}
-static void at91_gpio_set(struct gpio_chip *chip, unsigned offset,
- int val)
+static int at91_gpio_set(struct gpio_chip *chip, unsigned int offset, int val)
{
struct at91_gpio_chip *at91_gpio = gpiochip_get_data(chip);
void __iomem *pio = at91_gpio->regbase;
unsigned mask = 1 << offset;
writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR));
+
+ return 0;
}
-static void at91_gpio_set_multiple(struct gpio_chip *chip,
- unsigned long *mask, unsigned long *bits)
+static int at91_gpio_set_multiple(struct gpio_chip *chip,
+ unsigned long *mask, unsigned long *bits)
{
struct at91_gpio_chip *at91_gpio = gpiochip_get_data(chip);
void __iomem *pio = at91_gpio->regbase;
@@ -1469,6 +1473,8 @@ static void at91_gpio_set_multiple(struct gpio_chip *chip,
writel_relaxed(set_mask, pio + PIO_SODR);
writel_relaxed(clear_mask, pio + PIO_CODR);
+
+ return 0;
}
static int at91_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
@@ -1517,6 +1523,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.
@@ -1536,6 +1556,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);
@@ -1546,6 +1569,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);
@@ -1615,78 +1641,53 @@ static void gpio_irq_ack(struct irq_data *d)
/* the interrupt is already cleared before by reading ISR */
}
-#ifdef CONFIG_PM
-
-static u32 wakeups[MAX_GPIO_BANKS];
-static u32 backups[MAX_GPIO_BANKS];
-
static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
{
struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
- unsigned bank = at91_gpio->pioc_idx;
unsigned mask = 1 << d->hwirq;
- if (unlikely(bank >= MAX_GPIO_BANKS))
- return -EINVAL;
-
if (state)
- wakeups[bank] |= mask;
+ at91_gpio->wakeups |= mask;
else
- wakeups[bank] &= ~mask;
+ at91_gpio->wakeups &= ~mask;
irq_set_irq_wake(at91_gpio->pioc_virq, state);
return 0;
}
-void at91_pinctrl_gpio_suspend(void)
+static int at91_gpio_suspend(struct device *dev)
{
- int i;
+ struct at91_gpio_chip *at91_chip = dev_get_drvdata(dev);
+ void __iomem *pio = at91_chip->regbase;
- for (i = 0; i < gpio_banks; i++) {
- void __iomem *pio;
-
- if (!gpio_chips[i])
- continue;
-
- pio = gpio_chips[i]->regbase;
+ at91_chip->backups = readl_relaxed(pio + PIO_IMR);
+ writel_relaxed(at91_chip->backups, pio + PIO_IDR);
+ writel_relaxed(at91_chip->wakeups, pio + PIO_IER);
- backups[i] = readl_relaxed(pio + PIO_IMR);
- writel_relaxed(backups[i], pio + PIO_IDR);
- writel_relaxed(wakeups[i], pio + PIO_IER);
+ if (!at91_chip->wakeups)
+ clk_disable_unprepare(at91_chip->clock);
+ else
+ dev_dbg(dev, "GPIO-%c may wake for %08x\n",
+ 'A' + at91_chip->id, at91_chip->wakeups);
- if (!wakeups[i])
- clk_disable_unprepare(gpio_chips[i]->clock);
- else
- printk(KERN_DEBUG "GPIO-%c may wake for %08x\n",
- 'A'+i, wakeups[i]);
- }
+ return 0;
}
-void at91_pinctrl_gpio_resume(void)
+static int at91_gpio_resume(struct device *dev)
{
- int i;
+ struct at91_gpio_chip *at91_chip = dev_get_drvdata(dev);
+ void __iomem *pio = at91_chip->regbase;
- for (i = 0; i < gpio_banks; i++) {
- void __iomem *pio;
+ if (!at91_chip->wakeups)
+ clk_prepare_enable(at91_chip->clock);
- if (!gpio_chips[i])
- continue;
+ writel_relaxed(at91_chip->wakeups, pio + PIO_IDR);
+ writel_relaxed(at91_chip->backups, pio + PIO_IER);
- pio = gpio_chips[i]->regbase;
-
- if (!wakeups[i])
- clk_prepare_enable(gpio_chips[i]->clock);
-
- writel_relaxed(wakeups[i], pio + PIO_IDR);
- writel_relaxed(backups[i], pio + PIO_IER);
- }
+ return 0;
}
-#else
-#define gpio_irq_set_wake NULL
-#endif /* CONFIG_PM */
-
static void gpio_irq_handler(struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -1722,6 +1723,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);
@@ -1729,31 +1731,33 @@ 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 = gpio_irq_set_wake;
+ 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);
/*
- * Let the generic code handle this edge IRQ, the the chained
+ * Let the generic code handle this edge IRQ, the chained
* handler will perform the actual work of handling the parent
* 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;
@@ -1766,7 +1770,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)
@@ -1813,84 +1817,67 @@ 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;
+ int alias_idx;
int ret = 0;
int irq, i;
- int alias_idx = of_alias_get_id(np, "gpio");
uint32_t ngpio;
char **names;
+ alias_idx = of_alias_get_id(np, "gpio");
+ if (alias_idx < 0)
+ return alias_idx;
+
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 = 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 (IS_ERR(names))
+ return PTR_ERR(names);
for (i = 0; i < chip->ngpio; i++)
- names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i);
+ strreplace(names[i], '-', alias_idx + 'A');
chip->names = (const char *const *)names;
@@ -1904,32 +1891,28 @@ 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 DEFINE_NOIRQ_DEV_PM_OPS(at91_gpio_pm_ops, at91_gpio_suspend, at91_gpio_resume);
+
static struct platform_driver at91_gpio_driver = {
.driver = {
.name = "gpio-at91",
.of_match_table = at91_gpio_of_match,
+ .pm = pm_sleep_ptr(&at91_gpio_pm_ops),
},
.probe = at91_gpio_probe,
};