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