aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/pm.c
diff options
context:
space:
mode:
authorLothar Wassmann <LW@KARO-electronics.de>2005-12-12 11:44:05 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-12-12 11:44:05 -0500
commit1ee9530a71686436dbeb5f31dd5b925c39cf71d7 (patch)
treebd5ca62accb91f21f71edc5e456dcd070135a4e4 /arch/arm/mach-pxa/pm.c
parent22f975f4ffa707ea24507f6899bb9f5a1ff034bc (diff)
[ARM] 3201/1: PXA27x: Prevent hangup during resume due to inadvertedly enabling MBREQ (replaces: 3198/1)
Patch from Lothar Wassmann The patch makes sure, that the ouptut functions of pins are restored before restoring the Alternat Function settings, preventing pins from being intermediately configured for undefined or unwanted alternate functions. Here is the original comment: I've got a PXA270 system that uses GPIO80 as nCS4. This system did hang on resume. Digging into the problem I found that the processor stalled immediately when restoring the GAFR2_U register which restored the alternate function for GPIO80. Since the GPDR registers were restored after the GAFR registers, the offending GPIO was configured as input at this point. Thus the alternate function that was in effect after restoring the GAFR was in fact the input function "MBREQ" instead of the output function "nCS4". The "PXA27x Processor Family Developer's Manual" (Footnote in Table 6-1 on page 6-3) states that: "The MBREQ alternate function must not be enabled until the PSSR[RDH] bit field is cleared. For more details, see Table 3-15, "PSSR Bit Definitions" on page 3-71." There is another note in the Developer's Manual (chapter 24.4.2 "GPIO operation as Alternate Function" on page 24-4) stating that: "Configuring a GPIO for an alternate function that is not defined for it causes unpredictable results." Since some GPIOs have no input function defined, and to prevent inadvertedly programming the MBREQ function on some pin, the GAFR registers should be restored after the GPDR registers have been restored. Additional provisions have to be made when the MBREQ function is actually required. The corresponding GAFR bits should not be restored with the regular GAFR restore, but must be set only after the PSSR bits have been cleared. Signed-off-by: Lothar Wassmann <LW@KARO-electronics.de> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa/pm.c')
-rw-r--r--arch/arm/mach-pxa/pm.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index f74b9af112dc..852ea72d8c80 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -155,19 +155,20 @@ int pxa_pm_enter(suspend_state_t state)
155 PSPR = 0; 155 PSPR = 0;
156 156
157 /* restore registers */ 157 /* restore registers */
158 RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
159 RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
158 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 160 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
159 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 161 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
160 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 162 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
161 RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
162 RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
163 RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); 163 RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
164 RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); 164 RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
165 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 165 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
166 166
167#ifdef CONFIG_PXA27x 167#ifdef CONFIG_PXA27x
168 RESTORE(MDREFR); 168 RESTORE(MDREFR);
169 RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); 169 RESTORE_GPLEVEL(3); RESTORE(GPDR3);
170 RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); 170 RESTORE(GAFR3_L); RESTORE(GAFR3_U);
171 RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
171 RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); 172 RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
172 RESTORE(PFER); RESTORE(PKWR); 173 RESTORE(PFER); RESTORE(PKWR);
173#endif 174#endif