diff options
Diffstat (limited to 'arch/arm/mach-pxa/pxa25x.c')
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 305452b56e91..25d17a1dab78 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -36,6 +36,12 @@ | |||
36 | #include "devices.h" | 36 | #include "devices.h" |
37 | #include "clock.h" | 37 | #include "clock.h" |
38 | 38 | ||
39 | int cpu_is_pxa26x(void) | ||
40 | { | ||
41 | return cpu_is_pxa250() && ((BOOT_DEF & 0x8) == 0); | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(cpu_is_pxa26x); | ||
44 | |||
39 | /* | 45 | /* |
40 | * Various clock factors driven by the CCCR register. | 46 | * Various clock factors driven by the CCCR register. |
41 | */ | 47 | */ |
@@ -203,48 +209,21 @@ static struct clk pxa25x_clks[] = { | |||
203 | * More ones like CP and general purpose register values are preserved | 209 | * More ones like CP and general purpose register values are preserved |
204 | * with the stack pointer in sleep.S. | 210 | * with the stack pointer in sleep.S. |
205 | */ | 211 | */ |
206 | enum { SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, | 212 | enum { |
207 | |||
208 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | ||
209 | SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, | ||
210 | SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, | ||
211 | |||
212 | SLEEP_SAVE_PSTR, | 213 | SLEEP_SAVE_PSTR, |
213 | |||
214 | SLEEP_SAVE_CKEN, | 214 | SLEEP_SAVE_CKEN, |
215 | |||
216 | SLEEP_SAVE_COUNT | 215 | SLEEP_SAVE_COUNT |
217 | }; | 216 | }; |
218 | 217 | ||
219 | 218 | ||
220 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | 219 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) |
221 | { | 220 | { |
222 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); | ||
223 | |||
224 | SAVE(GAFR0_L); SAVE(GAFR0_U); | ||
225 | SAVE(GAFR1_L); SAVE(GAFR1_U); | ||
226 | SAVE(GAFR2_L); SAVE(GAFR2_U); | ||
227 | |||
228 | SAVE(CKEN); | 221 | SAVE(CKEN); |
229 | SAVE(PSTR); | 222 | SAVE(PSTR); |
230 | |||
231 | /* Clear GPIO transition detect bits */ | ||
232 | GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; | ||
233 | } | 223 | } |
234 | 224 | ||
235 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | 225 | static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) |
236 | { | 226 | { |
237 | /* ensure not to come back here if it wasn't intended */ | ||
238 | PSPR = 0; | ||
239 | |||
240 | /* restore registers */ | ||
241 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | ||
242 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | ||
243 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | ||
244 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | ||
245 | |||
246 | PSSR = PSSR_RDH | PSSR_PH; | ||
247 | |||
248 | RESTORE(CKEN); | 227 | RESTORE(CKEN); |
249 | RESTORE(PSTR); | 228 | RESTORE(PSTR); |
250 | } | 229 | } |
@@ -256,19 +235,32 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) | |||
256 | 235 | ||
257 | switch (state) { | 236 | switch (state) { |
258 | case PM_SUSPEND_MEM: | 237 | case PM_SUSPEND_MEM: |
259 | /* set resume return address */ | ||
260 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
261 | pxa25x_cpu_suspend(PWRMODE_SLEEP); | 238 | pxa25x_cpu_suspend(PWRMODE_SLEEP); |
262 | break; | 239 | break; |
263 | } | 240 | } |
264 | } | 241 | } |
265 | 242 | ||
243 | static int pxa25x_cpu_pm_prepare(void) | ||
244 | { | ||
245 | /* set resume return address */ | ||
246 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static void pxa25x_cpu_pm_finish(void) | ||
251 | { | ||
252 | /* ensure not to come back here if it wasn't intended */ | ||
253 | PSPR = 0; | ||
254 | } | ||
255 | |||
266 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { | 256 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { |
267 | .save_count = SLEEP_SAVE_COUNT, | 257 | .save_count = SLEEP_SAVE_COUNT, |
268 | .valid = suspend_valid_only_mem, | 258 | .valid = suspend_valid_only_mem, |
269 | .save = pxa25x_cpu_pm_save, | 259 | .save = pxa25x_cpu_pm_save, |
270 | .restore = pxa25x_cpu_pm_restore, | 260 | .restore = pxa25x_cpu_pm_restore, |
271 | .enter = pxa25x_cpu_pm_enter, | 261 | .enter = pxa25x_cpu_pm_enter, |
262 | .prepare = pxa25x_cpu_pm_prepare, | ||
263 | .finish = pxa25x_cpu_pm_finish, | ||
272 | }; | 264 | }; |
273 | 265 | ||
274 | static void __init pxa25x_init_pm(void) | 266 | static void __init pxa25x_init_pm(void) |
@@ -330,6 +322,8 @@ static struct sys_device pxa25x_sysdev[] = { | |||
330 | { | 322 | { |
331 | .cls = &pxa_irq_sysclass, | 323 | .cls = &pxa_irq_sysclass, |
332 | }, { | 324 | }, { |
325 | .cls = &pxa2xx_mfp_sysclass, | ||
326 | }, { | ||
333 | .cls = &pxa_gpio_sysclass, | 327 | .cls = &pxa_gpio_sysclass, |
334 | }, | 328 | }, |
335 | }; | 329 | }; |
@@ -338,11 +332,7 @@ static int __init pxa25x_init(void) | |||
338 | { | 332 | { |
339 | int i, ret = 0; | 333 | int i, ret = 0; |
340 | 334 | ||
341 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 335 | if (cpu_is_pxa25x()) { |
342 | if (cpu_is_pxa255()) | ||
343 | clks_register(&pxa25x_hwuart_clk, 1); | ||
344 | |||
345 | if (cpu_is_pxa21x() || cpu_is_pxa25x()) { | ||
346 | 336 | ||
347 | reset_status = RCSR; | 337 | reset_status = RCSR; |
348 | 338 | ||
@@ -365,9 +355,11 @@ static int __init pxa25x_init(void) | |||
365 | return ret; | 355 | return ret; |
366 | } | 356 | } |
367 | 357 | ||
368 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 358 | /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */ |
369 | if (cpu_is_pxa255()) | 359 | if (cpu_is_pxa255() || cpu_is_pxa26x()) { |
360 | clks_register(&pxa25x_hwuart_clk, 1); | ||
370 | ret = platform_device_register(&pxa_device_hwuart); | 361 | ret = platform_device_register(&pxa_device_hwuart); |
362 | } | ||
371 | 363 | ||
372 | return ret; | 364 | return ret; |
373 | } | 365 | } |