1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
Index: linux-2.6.21/arch/arm/mach-pxa/pxa27x.c
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/pxa27x.c 2007-06-28 19:44:28.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/pxa27x.c 2007-06-28 19:44:58.000000000 -0300
@@ -22,6 +22,10 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/ohci.h>
+#ifdef CONFIG_PXA_EZX
+#include <asm/arch/ezx.h>
+#endif
+
#include "generic.h"
/* Crystal clock: 13MHz */
@@ -156,7 +160,13 @@
break;
case PM_SUSPEND_MEM:
/* set resume return address */
+#ifdef CONFIG_PXA_EZX
+ /* 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;
+#else
PSPR = virt_to_phys(pxa_cpu_resume);
+#endif
pxa_cpu_suspend(PWRMODE_SLEEP);
break;
}
Index: linux-2.6.21/arch/arm/mach-pxa/pm.c
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/pm.c 2007-06-28 19:44:28.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/pm.c 2007-06-28 19:44:58.000000000 -0300
@@ -24,6 +24,10 @@
#include <asm/arch/lubbock.h>
#include <asm/mach/time.h>
+#ifdef CONFIG_PXA_EZX
+#include <asm/arch/ezx.h>
+#endif
+
/*
* Debug macros
@@ -152,8 +156,12 @@
}
/* ensure not to come back here if it wasn't intended */
+#ifdef CONFIG_PXA_EZX
+ *(unsigned long *)(phys_to_virt(RESUME_ADDR)) = 0;
+ *(unsigned long *)(phys_to_virt(FLAG_ADDR)) = OFF_FLAG;
+#else
PSPR = 0;
-
+#endif
/* restore registers */
RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
Index: linux-2.6.21/arch/arm/mach-pxa/ezx.c
===================================================================
--- linux-2.6.21.orig/arch/arm/mach-pxa/ezx.c 2007-06-28 19:44:52.000000000 -0300
+++ linux-2.6.21/arch/arm/mach-pxa/ezx.c 2007-06-28 19:44:58.000000000 -0300
@@ -19,6 +19,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/ohci.h>
#include <asm/arch/ezx.h>
+#include <asm/arch/system.h>
#include "generic.h"
@@ -122,8 +123,69 @@
&ezxbp_device,
};
+/* PM */
+extern int bp_handshake_passed(void);
+
+#define POWER_OFF_TIMEOUT (2*60*HZ)
+
+static void ezx_reboot_poweroff(char mode)
+{
+#ifdef CONFIG_EZX_BP
+ unsigned long start = jiffies;
+
+ printk("Waiting for BP to turn off. This can take some time...\n");
+ *(unsigned long *)(phys_to_virt(BPSIG_ADDR)) = NO_FLAG;
+ cpu_proc_fin();
+
+ do {
+ /*
+ * Turn off gracefully. Wait BP turn off first, and then
+ * properly turn off.
+ */
+ if (pxa_gpio_get_value(GPIO_BB_WDI) == 0) {
+ *(unsigned long *)(phys_to_virt(BPSIG_ADDR)) = WDI_FLAG;
+
+ /* reset BP */
+ pxa_gpio_set_value(GPIO_BB_RESET, 0);
+ mdelay(1);
+ pxa_gpio_set_value(GPIO_BB_RESET, 1);
+
+ if (mode == 'z')
+ arch_reset('h');
+ break;
+ }
+ /* Just turn it off! */
+ if (!bp_handshake_passed() || !pxa_gpio_get_value(GPIO_BB_WDI2)
+ || (jiffies - start) >= POWER_OFF_TIMEOUT) {
+ break;
+ }
+ } while(1);
+#endif
+
+ if (mode == 'z')
+ /* Panic! Ask PCAP to turn both processors off */
+ pxa_gpio_set_value(GPIO_WDI_AP, 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);
+}
+
static int __init ezx_init(void)
{
+ pm_power_off = ezx_poweroff;
+ arm_pm_restart = ezx_restart;
+
CKEN = CKEN9_OSTIMER | CKEN22_MEMC;
pxa_gpio_mode(GPIO_ICL_FFRXD_MD);
|