diff options
Diffstat (limited to 'arch/arm/mach-pxa/palmz72.c')
-rw-r--r-- | arch/arm/mach-pxa/palmz72.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index a90b4d77a201..2f730da3bba8 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c | |||
@@ -449,6 +449,80 @@ static struct pxafb_mach_info palmz72_lcd_screen = { | |||
449 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, | 449 | .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, |
450 | }; | 450 | }; |
451 | 451 | ||
452 | #ifdef CONFIG_PM | ||
453 | |||
454 | /* We have some black magic here | ||
455 | * PalmOS ROM on recover expects special struct physical address | ||
456 | * to be transferred via PSPR. Using this struct PalmOS restores | ||
457 | * its state after sleep. As for Linux, we need to setup it the | ||
458 | * same way. More than that, PalmOS ROM changes some values in memory. | ||
459 | * For now only one location is found, which needs special treatment. | ||
460 | * Thanks to Alex Osborne, Andrzej Zaborowski, and lots of other people | ||
461 | * for reading backtraces for me :) | ||
462 | */ | ||
463 | |||
464 | #define PALMZ72_SAVE_DWORD ((unsigned long *)0xc0000050) | ||
465 | |||
466 | static struct palmz72_resume_info palmz72_resume_info = { | ||
467 | .magic0 = 0xb4e6, | ||
468 | .magic1 = 1, | ||
469 | |||
470 | /* reset state, MMU off etc */ | ||
471 | .arm_control = 0, | ||
472 | .aux_control = 0, | ||
473 | .ttb = 0, | ||
474 | .domain_access = 0, | ||
475 | .process_id = 0, | ||
476 | }; | ||
477 | |||
478 | static unsigned long store_ptr; | ||
479 | |||
480 | /* sys_device for Palm Zire 72 PM */ | ||
481 | |||
482 | static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg) | ||
483 | { | ||
484 | /* setup the resume_info struct for the original bootloader */ | ||
485 | palmz72_resume_info.resume_addr = (u32) pxa_cpu_resume; | ||
486 | |||
487 | /* Storing memory touched by ROM */ | ||
488 | store_ptr = *PALMZ72_SAVE_DWORD; | ||
489 | |||
490 | /* Setting PSPR to a proper value */ | ||
491 | PSPR = virt_to_phys(&palmz72_resume_info); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static int palmz72_pm_resume(struct sys_device *dev) | ||
497 | { | ||
498 | *PALMZ72_SAVE_DWORD = store_ptr; | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static struct sysdev_class palmz72_pm_sysclass = { | ||
503 | .name = "palmz72_pm", | ||
504 | .suspend = palmz72_pm_suspend, | ||
505 | .resume = palmz72_pm_resume, | ||
506 | }; | ||
507 | |||
508 | static struct sys_device palmz72_pm_device = { | ||
509 | .cls = &palmz72_pm_sysclass, | ||
510 | }; | ||
511 | |||
512 | static int __init palmz72_pm_init(void) | ||
513 | { | ||
514 | int ret = -ENODEV; | ||
515 | if (machine_is_palmz72()) { | ||
516 | ret = sysdev_class_register(&palmz72_pm_sysclass); | ||
517 | if (ret == 0) | ||
518 | ret = sysdev_register(&palmz72_pm_device); | ||
519 | } | ||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | device_initcall(palmz72_pm_init); | ||
524 | #endif | ||
525 | |||
452 | /****************************************************************************** | 526 | /****************************************************************************** |
453 | * Machine init | 527 | * Machine init |
454 | ******************************************************************************/ | 528 | ******************************************************************************/ |