aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-01-08 10:12:22 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-01-26 10:07:56 -0500
commitd4fc858f9cfec5200a957c305d61ffc28c5d7796 (patch)
tree489836868e789f248cbff692d0403b6c590597dd /arch/arm
parent7f7c8a619253c83cf3b1071df3b001811d0c1a6c (diff)
[ARM] pxa: program MFPs for low power mode when suspending
Hook the MFP code into the power management code so that the MFPs can be reconfigured when suspending and resuming. However, note the FIXME - low power mode MFP configuration may depend on the system state being entered. Also note that we have to clear any detected edge events prior to entering a low power mode - otherwise we immediately wake up. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-pxa/mfp.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
index c66b1cd7df64..ec1b2d8f61c4 100644
--- a/arch/arm/mach-pxa/mfp.c
+++ b/arch/arm/mach-pxa/mfp.c
@@ -17,6 +17,7 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/sysdev.h>
20 21
21#include <asm/hardware.h> 22#include <asm/hardware.h>
22#include <asm/arch/mfp.h> 23#include <asm/arch/mfp.h>
@@ -87,8 +88,13 @@ static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
87 88
88static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p) 89static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
89{ 90{
90 if (mfp_configured(p) && p->mfpr_lpm != p->mfpr_run) 91 if (mfp_configured(p)) {
91 mfpr_writel(p->mfpr_off, p->mfpr_lpm); 92 unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
93 if (mfpr_clr != p->mfpr_run)
94 mfpr_writel(p->mfpr_off, mfpr_clr);
95 if (p->mfpr_lpm != mfpr_clr)
96 mfpr_writel(p->mfpr_off, p->mfpr_lpm);
97 }
92} 98}
93 99
94void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num) 100void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
@@ -189,3 +195,52 @@ void __init pxa3xx_init_mfp(void)
189 for (i = 0; i < ARRAY_SIZE(mfp_table); i++) 195 for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
190 mfp_table[i].config = -1; 196 mfp_table[i].config = -1;
191} 197}
198
199#ifdef CONFIG_PM
200/*
201 * Configure the MFPs appropriately for suspend/resume.
202 * FIXME: this should probably depend on which system state we're
203 * entering - for instance, we might not want to place MFP pins in
204 * a pull-down mode if they're an active low chip select, and we're
205 * just entering standby.
206 */
207static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
208{
209 int pin;
210
211 for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
212 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
213 __mfp_config_lpm(p);
214 }
215 return 0;
216}
217
218static int pxa3xx_mfp_resume(struct sys_device *d)
219{
220 int pin;
221
222 for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
223 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
224 __mfp_config_run(p);
225 }
226 return 0;
227}
228
229static struct sysdev_class mfp_sysclass = {
230 set_kset_name("mfp"),
231 .suspend = pxa3xx_mfp_suspend,
232 .resume = pxa3xx_mfp_resume,
233};
234
235static struct sys_device mfp_device = {
236 .id = 0,
237 .cls = &mfp_sysclass,
238};
239
240static int __init mfp_init_devicefs(void)
241{
242 sysdev_class_register(&mfp_sysclass);
243 return sysdev_register(&mfp_device);
244}
245device_initcall(mfp_init_devicefs);
246#endif