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));

Reply via email to