|
@@ -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;
|
|
|
}
|