lkml.org 
[lkml]   [2017]   [Apr]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] pinctrl: at91-pio4: handle suspend to ram
Date
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: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
drivers/pinctrl/pinctrl-at91-pio4.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
index 28bbc1bb9e6c..dc8591543dee 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -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;
}
--
2.11.0
\
 
 \ /
  Last update: 2017-04-06 15:37    [W:0.074 / U:0.020 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site