aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Belloni <alexandre.belloni@free-electrons.com>2017-04-06 09:36:23 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-04-07 08:32:51 -0400
commitba9e7f2794d8158c93aacd279830a6f1f98b19b0 (patch)
tree68d98fa179f3d28fa50406f9aa163e7ff048ee0a
parent8d5e7c5df0a6c442373628be5221321172b1badf (diff)
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: Alexandre Belloni <alexandre.belloni@free-electrons.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pinctrl-at91-pio4.c34
1 files 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 {
126 struct irq_domain *irq_domain; 126 struct irq_domain *irq_domain;
127 int *irqs; 127 int *irqs;
128 unsigned *pm_wakeup_sources; 128 unsigned *pm_wakeup_sources;
129 unsigned *pm_suspend_backup; 129 struct {
130 u32 imr;
131 u32 odsr;
132 u32 cfgr[ATMEL_PIO_NPINS_PER_BANK];
133 } *pm_suspend_backup;
130 struct device *dev; 134 struct device *dev;
131 struct device_node *node; 135 struct device_node *node;
132}; 136};
@@ -830,17 +834,26 @@ static int __maybe_unused atmel_pctrl_suspend(struct device *dev)
830{ 834{
831 struct platform_device *pdev = to_platform_device(dev); 835 struct platform_device *pdev = to_platform_device(dev);
832 struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); 836 struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
833 int i; 837 int i, j;
834 838
835 /* 839 /*
836 * For each bank, save IMR to restore it later and disable all GPIO 840 * For each bank, save IMR to restore it later and disable all GPIO
837 * interrupts excepting the ones marked as wakeup sources. 841 * interrupts excepting the ones marked as wakeup sources.
838 */ 842 */
839 for (i = 0; i < atmel_pioctrl->nbanks; i++) { 843 for (i = 0; i < atmel_pioctrl->nbanks; i++) {
840 atmel_pioctrl->pm_suspend_backup[i] = 844 atmel_pioctrl->pm_suspend_backup[i].imr =
841 atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_IMR); 845 atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_IMR);
842 atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IDR, 846 atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IDR,
843 ~atmel_pioctrl->pm_wakeup_sources[i]); 847 ~atmel_pioctrl->pm_wakeup_sources[i]);
848 atmel_pioctrl->pm_suspend_backup[i].odsr =
849 atmel_gpio_read(atmel_pioctrl, i, ATMEL_PIO_ODSR);
850 for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) {
851 atmel_gpio_write(atmel_pioctrl, i,
852 ATMEL_PIO_MSKR, BIT(j));
853 atmel_pioctrl->pm_suspend_backup[i].cfgr[j] =
854 atmel_gpio_read(atmel_pioctrl, i,
855 ATMEL_PIO_CFGR);
856 }
844 } 857 }
845 858
846 return 0; 859 return 0;
@@ -850,11 +863,20 @@ static int __maybe_unused atmel_pctrl_resume(struct device *dev)
850{ 863{
851 struct platform_device *pdev = to_platform_device(dev); 864 struct platform_device *pdev = to_platform_device(dev);
852 struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); 865 struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
853 int i; 866 int i, j;
854 867
855 for (i = 0; i < atmel_pioctrl->nbanks; i++) 868 for (i = 0; i < atmel_pioctrl->nbanks; i++) {
856 atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IER, 869 atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_IER,
857 atmel_pioctrl->pm_suspend_backup[i]); 870 atmel_pioctrl->pm_suspend_backup[i].imr);
871 atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_SODR,
872 atmel_pioctrl->pm_suspend_backup[i].odsr);
873 for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) {
874 atmel_gpio_write(atmel_pioctrl, i,
875 ATMEL_PIO_MSKR, BIT(j));
876 atmel_gpio_write(atmel_pioctrl, i, ATMEL_PIO_CFGR,
877 atmel_pioctrl->pm_suspend_backup[i].cfgr[j]);
878 }
879 }
858 880
859 return 0; 881 return 0;
860} 882}