Hello, I did some work with the power management functions, but i'm not sure if this is finished yet. So feedback is welcome.
Bart diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 44c5bfe..e2a4219 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -41,6 +41,7 @@ #include <mach/mfp-pxa27x.h> #include <mach/pxa-regs.h> #include <mach/pxa2xx-regs.h> +#include <mach/pm.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/io.h> @@ -223,6 +224,87 @@ static unsigned long ezx_pin_config[] __initdata = { GPIO113_USB_P3_3, }; +/* PM */ +/* + * Flags in memory for sleep use + */ +#define FLAG_ADDR PHYS_OFFSET +#define RESUME_ADDR (PHYS_OFFSET + 4) +#define BPSIG_ADDR (PHYS_OFFSET + 8) + +#define USER_OFF_FLAG 0x5a5a5a5a +#define SLEEP_FLAG 0x6b6b6b6b +#define OFF_FLAG 0x7c7c7c7c +#define REFLASH_FLAG 0x0C1D2E3F +#define PASS_THRU_FLAG 0x12345678 + +#define WDI_FLAG 0xbb00dead +#define NO_FLAG 0xaa00dead + +#define GPIO_BB_WDI 13 /* BB_WDI */ +#define GPIO_BB_RESET 82 /* BB_RESET */ + /* 57 in E680_P3_AND_EARLY */ + +static void ezx_reboot_poweroff(char mode) +{ + *(unsigned long *)(phys_to_virt(BPSIG_ADDR)) = NO_FLAG; + cpu_proc_fin(); + +#ifdef CONFIG_EZX_BP + if (gpio_get_value(GPIO_BB_WDI) == 0) { + *(unsigned long *)(phys_to_virt(BPSIG_ADDR)) = WDI_FLAG; + + /* reset BP */ + gpio_set_value(GPIO_BB_RESET, 0); + mdelay(1); + gpio_set_value(GPIO_BB_RESET, 1); + + if (mode == 'z') { + arch_reset('h'); + while (1) + ; + } + } +#endif + if (mode == 'z') { + /* Panic! Ask PCAP to turn both processors off */ + gpio_direction_output(MFP_PIN_GPIO4, 0); + } else { + arm_machine_restart(mode); + } + + while (1) + ; +} + +static inline void ezx_poweroff(void) +{ + ezx_reboot_poweroff('z'); +} + +static inline void ezx_restart(char mode) +{ + ezx_reboot_poweroff(mode); +} + +#ifdef CONFIG_PM +static int ezx_pm_prepare(void) +{ +printk(KERN_DEBUG "ezx_pm_prepare\n"); + /* set EZX flags for blob - WM */ + *(unsigned long *)(phys_to_virt(RESUME_ADDR)) = virt_to_phys(pxa_cpu_resume); + *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = SLEEP_FLAG; + return 0; +} + +static void ezx_pm_finish(void) +{ +printk(KERN_DEBUG "ezx_pm_finish\n"); + *(unsigned long *)(phys_to_virt(RESUME_ADDR)) = 0; + *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = OFF_FLAG; +} +#endif + #if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680) static unsigned long gen1_pin_config[] __initdata = { /* flip / lockswitch */ @@ -972,6 +1054,12 @@ static struct i2c_board_info __initdata a780_i2c_board_info[] = { static void __init a780_init(void) { +#ifdef CONFIG_PM + pxa_cpu_pm_fns->prepare = ezx_pm_prepare; + pxa_cpu_pm_fns->finish = ezx_pm_finish; +#endif + pm_power_off = ezx_poweroff; + arm_pm_restart = ezx_restart; pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config)); pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config)); pxa2xx_mfp_config(ARRAY_AND_SIZE(a780_pin_config));