[ARM] 5239/1: Palm Zire 72 power management support

This patch contains Palm Zire 72 power
management support.

Depends on #5238/1

Signed-off-by: Sergey Lapin <slapin@ossfans.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Sergey Lapin 2008-08-29 15:53:24 +01:00 committed by Russell King
parent d8aa0251f1
commit fda50a1c49
2 changed files with 87 additions and 0 deletions

View File

@ -63,5 +63,18 @@
#define PALMZ72_PRESCALER 0x3F
#define PALMZ72_PERIOD_NS 3500
#ifdef CONFIG_PM
struct palmz72_resume_info {
u32 magic0; /* 0x0 */
u32 magic1; /* 0x4 */
u32 resume_addr; /* 0x8 */
u32 pad[11]; /* 0xc..0x37 */
u32 arm_control; /* 0x38 */
u32 aux_control; /* 0x3c */
u32 ttb; /* 0x40 */
u32 domain_access; /* 0x44 */
u32 process_id; /* 0x48 */
};
#endif
#endif

View File

@ -449,6 +449,80 @@ static struct pxafb_mach_info palmz72_lcd_screen = {
.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
};
#ifdef CONFIG_PM
/* We have some black magic here
* PalmOS ROM on recover expects special struct physical address
* to be transferred via PSPR. Using this struct PalmOS restores
* its state after sleep. As for Linux, we need to setup it the
* same way. More than that, PalmOS ROM changes some values in memory.
* For now only one location is found, which needs special treatment.
* Thanks to Alex Osborne, Andrzej Zaborowski, and lots of other people
* for reading backtraces for me :)
*/
#define PALMZ72_SAVE_DWORD ((unsigned long *)0xc0000050)
static struct palmz72_resume_info palmz72_resume_info = {
.magic0 = 0xb4e6,
.magic1 = 1,
/* reset state, MMU off etc */
.arm_control = 0,
.aux_control = 0,
.ttb = 0,
.domain_access = 0,
.process_id = 0,
};
static unsigned long store_ptr;
/* sys_device for Palm Zire 72 PM */
static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
{
/* setup the resume_info struct for the original bootloader */
palmz72_resume_info.resume_addr = (u32) pxa_cpu_resume;
/* Storing memory touched by ROM */
store_ptr = *PALMZ72_SAVE_DWORD;
/* Setting PSPR to a proper value */
PSPR = virt_to_phys(&palmz72_resume_info);
return 0;
}
static int palmz72_pm_resume(struct sys_device *dev)
{
*PALMZ72_SAVE_DWORD = store_ptr;
return 0;
}
static struct sysdev_class palmz72_pm_sysclass = {
.name = "palmz72_pm",
.suspend = palmz72_pm_suspend,
.resume = palmz72_pm_resume,
};
static struct sys_device palmz72_pm_device = {
.cls = &palmz72_pm_sysclass,
};
static int __init palmz72_pm_init(void)
{
int ret = -ENODEV;
if (machine_is_palmz72()) {
ret = sysdev_class_register(&palmz72_pm_sysclass);
if (ret == 0)
ret = sysdev_register(&palmz72_pm_device);
}
return ret;
}
device_initcall(palmz72_pm_init);
#endif
/******************************************************************************
* Machine init
******************************************************************************/