aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorLudovic Desroches <ludovic.desroches@atmel.com>2013-03-08 10:18:21 -0500
committerNicolas Ferre <nicolas.ferre@atmel.com>2013-03-14 04:37:42 -0400
commit647f8d94a4e69d39e88a617846755655853c20f5 (patch)
treed673cac675a6281094f72d39046cd5854e129f10 /drivers/pinctrl
parent7f06472f1c3281abceea36059f94e099bfe4698f (diff)
ARM: at91: add gpio suspend/resume support when using pinctrl
gpio suspend/resume and wakeup sources where not managed when using pinctrl so it was impossible to wake up the system with a gpio. Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-at91.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 75933a6aa828..efb7f10e902a 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -1277,21 +1277,80 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type)
1277} 1277}
1278 1278
1279#ifdef CONFIG_PM 1279#ifdef CONFIG_PM
1280
1281static u32 wakeups[MAX_GPIO_BANKS];
1282static u32 backups[MAX_GPIO_BANKS];
1283
1280static int gpio_irq_set_wake(struct irq_data *d, unsigned state) 1284static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
1281{ 1285{
1282 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); 1286 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
1283 unsigned bank = at91_gpio->pioc_idx; 1287 unsigned bank = at91_gpio->pioc_idx;
1288 unsigned mask = 1 << d->hwirq;
1284 1289
1285 if (unlikely(bank >= MAX_GPIO_BANKS)) 1290 if (unlikely(bank >= MAX_GPIO_BANKS))
1286 return -EINVAL; 1291 return -EINVAL;
1287 1292
1293 if (state)
1294 wakeups[bank] |= mask;
1295 else
1296 wakeups[bank] &= ~mask;
1297
1288 irq_set_irq_wake(at91_gpio->pioc_virq, state); 1298 irq_set_irq_wake(at91_gpio->pioc_virq, state);
1289 1299
1290 return 0; 1300 return 0;
1291} 1301}
1302
1303void at91_pinctrl_gpio_suspend(void)
1304{
1305 int i;
1306
1307 for (i = 0; i < gpio_banks; i++) {
1308 void __iomem *pio;
1309
1310 if (!gpio_chips[i])
1311 continue;
1312
1313 pio = gpio_chips[i]->regbase;
1314
1315 backups[i] = __raw_readl(pio + PIO_IMR);
1316 __raw_writel(backups[i], pio + PIO_IDR);
1317 __raw_writel(wakeups[i], pio + PIO_IER);
1318
1319 if (!wakeups[i]) {
1320 clk_unprepare(gpio_chips[i]->clock);
1321 clk_disable(gpio_chips[i]->clock);
1322 } else {
1323 printk(KERN_DEBUG "GPIO-%c may wake for %08x\n",
1324 'A'+i, wakeups[i]);
1325 }
1326 }
1327}
1328
1329void at91_pinctrl_gpio_resume(void)
1330{
1331 int i;
1332
1333 for (i = 0; i < gpio_banks; i++) {
1334 void __iomem *pio;
1335
1336 if (!gpio_chips[i])
1337 continue;
1338
1339 pio = gpio_chips[i]->regbase;
1340
1341 if (!wakeups[i]) {
1342 if (clk_prepare(gpio_chips[i]->clock) == 0)
1343 clk_enable(gpio_chips[i]->clock);
1344 }
1345
1346 __raw_writel(wakeups[i], pio + PIO_IDR);
1347 __raw_writel(backups[i], pio + PIO_IER);
1348 }
1349}
1350
1292#else 1351#else
1293#define gpio_irq_set_wake NULL 1352#define gpio_irq_set_wake NULL
1294#endif 1353#endif /* CONFIG_PM */
1295 1354
1296static struct irq_chip gpio_irqchip = { 1355static struct irq_chip gpio_irqchip = {
1297 .name = "GPIO", 1356 .name = "GPIO",