Commit ba9e7f27 authored by Alexandre Belloni's avatar Alexandre Belloni Committed by Linus Walleij

pinctrl: at91-pio4: handle suspend to ram

When suspending to RAM, the power to the core is cut and the register
values are lost. Save and restore more registers than just IMR.
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Linus Walleij's avatarLinus Walleij <linus.walleij@linaro.org>
parent 8d5e7c5d
......@@ -126,7 +126,11 @@ struct atmel_pioctrl {
struct irq_domain *irq_domain;
int *irqs;
unsigned *pm_wakeup_sources;
unsigned *pm_suspend_backup;
struct {
u32 imr;
u32 odsr;
u32 cfgr[ATMEL_PIO_NPINS_PER_BANK];
} *pm_suspend_backup;
struct device *dev;
struct device_node *node;
};
......@@ -830,17 +834,26 @@ static int __maybe_unused atmel_pctrl_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
int i;
int i, j;
/*
* For each bank, save IMR to restore it later and disable all GPIO
* interrupts excepting the ones marked as wakeup sources.
*/
for (i = 0; i < atmel_pioctrl->nbanks; i++) {
atmel_pioctrl->pm_suspend_backup[i] =
atmel_pioctrl->pm_suspend_backup[i].imr =
atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_IMR);
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IDR,
~atmel_pioctrl->pm_wakeup_sources[i]);
atmel_pioctrl->pm_suspend_backup[i].odsr =
atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_ODSR);
for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) {
atmel_gpio_write(atmel_pioctrl, i,
ATMEL_PIO_MSKR, BIT(j));
atmel_pioctrl->pm_suspend_backup[i].cfgr[j] =
atmel_gpio_read(atmel_pioctrl, i,
ATMEL_PIO_CFGR);
}
}
return 0;
......@@ -850,11 +863,20 @@ static int __maybe_unused atmel_pctrl_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
int i;
int i, j;
for (i = 0; i < atmel_pioctrl->nbanks; i++)
for (i = 0; i < atmel_pioctrl->nbanks; i++) {
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IER,
atmel_pioctrl->pm_suspend_backup[i]);
atmel_pioctrl->pm_suspend_backup[i].imr);
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_SODR,
atmel_pioctrl->pm_suspend_backup[i].odsr);
for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) {
atmel_gpio_write(atmel_pioctrl, i,
ATMEL_PIO_MSKR, BIT(j));
atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_CFGR,
atmel_pioctrl->pm_suspend_backup[i].cfgr[j]);
}
}
return 0;
}
......
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