diff options
Diffstat (limited to 'arch/arm/mach-pxa/pxa25x.c')
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 109 |
1 files changed, 91 insertions, 18 deletions
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index f36ca448338e..6dfcca72e90f 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -110,26 +110,99 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | |||
110 | 110 | ||
111 | #ifdef CONFIG_PM | 111 | #ifdef CONFIG_PM |
112 | 112 | ||
113 | void pxa_cpu_pm_enter(suspend_state_t state) | 113 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
114 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | ||
115 | |||
116 | #define RESTORE_GPLEVEL(n) do { \ | ||
117 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
118 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
119 | } while (0) | ||
120 | |||
121 | /* | ||
122 | * List of global PXA peripheral registers to preserve. | ||
123 | * More ones like CP and general purpose register values are preserved | ||
124 | * with the stack pointer in sleep.S. | ||
125 | */ | ||
126 | enum { SLEEP_SAVE_START = 0, | ||
127 | |||
128 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, | ||
129 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, | ||
130 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, | ||
131 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, | ||
132 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, | ||
133 | |||
134 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | ||
135 | SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, | ||
136 | SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, | ||
137 | |||
138 | SLEEP_SAVE_PSTR, | ||
139 | |||
140 | SLEEP_SAVE_ICMR, | ||
141 | SLEEP_SAVE_CKEN, | ||
142 | |||
143 | SLEEP_SAVE_SIZE | ||
144 | }; | ||
145 | |||
146 | |||
147 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | ||
148 | { | ||
149 | SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); | ||
150 | SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); | ||
151 | SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); | ||
152 | SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); | ||
153 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); | ||
154 | |||
155 | SAVE(GAFR0_L); SAVE(GAFR0_U); | ||
156 | SAVE(GAFR1_L); SAVE(GAFR1_U); | ||
157 | SAVE(GAFR2_L); SAVE(GAFR2_U); | ||
158 | |||
159 | SAVE(ICMR); | ||
160 | SAVE(CKEN); | ||
161 | SAVE(PSTR); | ||
162 | } | ||
163 | |||
164 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | ||
114 | { | 165 | { |
115 | extern void pxa_cpu_suspend(unsigned int); | 166 | /* restore registers */ |
116 | extern void pxa_cpu_resume(void); | 167 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); |
168 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); | ||
169 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | ||
170 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | ||
171 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | ||
172 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); | ||
173 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); | ||
174 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | ||
175 | |||
176 | RESTORE(CKEN); | ||
177 | RESTORE(ICMR); | ||
178 | RESTORE(PSTR); | ||
179 | } | ||
117 | 180 | ||
181 | static void pxa25x_cpu_pm_enter(suspend_state_t state) | ||
182 | { | ||
118 | CKEN = 0; | 183 | CKEN = 0; |
119 | 184 | ||
120 | switch (state) { | 185 | switch (state) { |
121 | case PM_SUSPEND_MEM: | 186 | case PM_SUSPEND_MEM: |
122 | /* set resume return address */ | 187 | /* set resume return address */ |
123 | PSPR = virt_to_phys(pxa_cpu_resume); | 188 | PSPR = virt_to_phys(pxa_cpu_resume); |
124 | pxa_cpu_suspend(PWRMODE_SLEEP); | 189 | pxa25x_cpu_suspend(PWRMODE_SLEEP); |
125 | break; | 190 | break; |
126 | } | 191 | } |
127 | } | 192 | } |
128 | 193 | ||
129 | static struct pm_ops pxa25x_pm_ops = { | 194 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { |
130 | .enter = pxa_pm_enter, | 195 | .save_size = SLEEP_SAVE_SIZE, |
131 | .valid = pm_valid_only_mem, | 196 | .valid = pm_valid_only_mem, |
197 | .save = pxa25x_cpu_pm_save, | ||
198 | .restore = pxa25x_cpu_pm_restore, | ||
199 | .enter = pxa25x_cpu_pm_enter, | ||
132 | }; | 200 | }; |
201 | |||
202 | static void __init pxa25x_init_pm(void) | ||
203 | { | ||
204 | pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; | ||
205 | } | ||
133 | #endif | 206 | #endif |
134 | 207 | ||
135 | void __init pxa25x_init_irq(void) | 208 | void __init pxa25x_init_irq(void) |
@@ -139,16 +212,16 @@ void __init pxa25x_init_irq(void) | |||
139 | } | 212 | } |
140 | 213 | ||
141 | static struct platform_device *pxa25x_devices[] __initdata = { | 214 | static struct platform_device *pxa25x_devices[] __initdata = { |
142 | &pxamci_device, | 215 | &pxa_device_mci, |
143 | &pxaudc_device, | 216 | &pxa_device_udc, |
144 | &pxafb_device, | 217 | &pxa_device_fb, |
145 | &ffuart_device, | 218 | &pxa_device_ffuart, |
146 | &btuart_device, | 219 | &pxa_device_btuart, |
147 | &stuart_device, | 220 | &pxa_device_stuart, |
148 | &pxai2c_device, | 221 | &pxa_device_i2c, |
149 | &pxai2s_device, | 222 | &pxa_device_i2s, |
150 | &pxaficp_device, | 223 | &pxa_device_ficp, |
151 | &pxartc_device, | 224 | &pxa_device_rtc, |
152 | }; | 225 | }; |
153 | 226 | ||
154 | static int __init pxa25x_init(void) | 227 | static int __init pxa25x_init(void) |
@@ -159,14 +232,14 @@ static int __init pxa25x_init(void) | |||
159 | if ((ret = pxa_init_dma(16))) | 232 | if ((ret = pxa_init_dma(16))) |
160 | return ret; | 233 | return ret; |
161 | #ifdef CONFIG_PM | 234 | #ifdef CONFIG_PM |
162 | pm_set_ops(&pxa25x_pm_ops); | 235 | pxa25x_init_pm(); |
163 | #endif | 236 | #endif |
164 | ret = platform_add_devices(pxa25x_devices, | 237 | ret = platform_add_devices(pxa25x_devices, |
165 | ARRAY_SIZE(pxa25x_devices)); | 238 | ARRAY_SIZE(pxa25x_devices)); |
166 | } | 239 | } |
167 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 240 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ |
168 | if (cpu_is_pxa25x()) | 241 | if (cpu_is_pxa25x()) |
169 | ret = platform_device_register(&hwuart_device); | 242 | ret = platform_device_register(&pxa_device_hwuart); |
170 | 243 | ||
171 | return ret; | 244 | return ret; |
172 | } | 245 | } |