aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/generic.c57
-rw-r--r--arch/arm/mach-pxa/generic.h1
-rw-r--r--arch/arm/mach-pxa/pxa25x.c19
-rw-r--r--arch/arm/mach-pxa/pxa27x.c23
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c2
5 files changed, 64 insertions, 38 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 698aeec52961..76970598f550 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -23,6 +23,7 @@
23#include <linux/ioport.h> 23#include <linux/ioport.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/sysdev.h>
26 27
27#include <asm/hardware.h> 28#include <asm/hardware.h>
28#include <asm/irq.h> 29#include <asm/irq.h>
@@ -226,3 +227,59 @@ void __init pxa_map_io(void)
226 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 227 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
227 get_clk_frequency_khz(1); 228 get_clk_frequency_khz(1);
228} 229}
230
231#ifdef CONFIG_PM
232
233static unsigned long saved_gplr[4];
234static unsigned long saved_gpdr[4];
235static unsigned long saved_grer[4];
236static unsigned long saved_gfer[4];
237
238static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
239{
240 int i, gpio;
241
242 for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
243 saved_gplr[i] = GPLR(gpio);
244 saved_gpdr[i] = GPDR(gpio);
245 saved_grer[i] = GRER(gpio);
246 saved_gfer[i] = GFER(gpio);
247
248 /* Clear GPIO transition detect bits */
249 GEDR(gpio) = GEDR(gpio);
250 }
251 return 0;
252}
253
254static int pxa_gpio_resume(struct sys_device *dev)
255{
256 int i, gpio;
257
258 for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
259 /* restore level with set/clear */
260 GPSR(gpio) = saved_gplr[i];
261 GPCR(gpio) = ~saved_gplr[i];
262
263 GRER(gpio) = saved_grer[i];
264 GFER(gpio) = saved_gfer[i];
265 GPDR(gpio) = saved_gpdr[i];
266 }
267 return 0;
268}
269#else
270#define pxa_gpio_suspend NULL
271#define pxa_gpio_resume NULL
272#endif
273
274struct sysdev_class pxa_gpio_sysclass = {
275 .name = "gpio",
276 .suspend = pxa_gpio_suspend,
277 .resume = pxa_gpio_resume,
278};
279
280static int __init pxa_gpio_init(void)
281{
282 return sysdev_class_register(&pxa_gpio_sysclass);
283}
284
285core_initcall(pxa_gpio_init);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 367b67923e11..1a16ad3ecee6 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -54,3 +54,4 @@ extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
54#endif 54#endif
55 55
56extern struct sysdev_class pxa_irq_sysclass; 56extern struct sysdev_class pxa_irq_sysclass;
57extern struct sysdev_class pxa_gpio_sysclass;
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 797635eec6b6..599e53fcc2c5 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -142,11 +142,6 @@ static struct clk pxa25x_clks[] = {
142#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 142#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
143#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 143#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
144 144
145#define RESTORE_GPLEVEL(n) do { \
146 GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
147 GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
148} while (0)
149
150/* 145/*
151 * List of global PXA peripheral registers to preserve. 146 * List of global PXA peripheral registers to preserve.
152 * More ones like CP and general purpose register values are preserved 147 * More ones like CP and general purpose register values are preserved
@@ -154,10 +149,6 @@ static struct clk pxa25x_clks[] = {
154 */ 149 */
155enum { SLEEP_SAVE_START = 0, 150enum { SLEEP_SAVE_START = 0,
156 151
157 SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2,
158 SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
159 SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
160 SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
161 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, 152 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
162 153
163 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 154 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
@@ -174,10 +165,6 @@ enum { SLEEP_SAVE_START = 0,
174 165
175static void pxa25x_cpu_pm_save(unsigned long *sleep_save) 166static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
176{ 167{
177 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
178 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
179 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
180 SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
181 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); 168 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
182 169
183 SAVE(GAFR0_L); SAVE(GAFR0_U); 170 SAVE(GAFR0_L); SAVE(GAFR0_U);
@@ -197,13 +184,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
197 PSPR = 0; 184 PSPR = 0;
198 185
199 /* restore registers */ 186 /* restore registers */
200 RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
201 RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
202 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 187 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
203 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 188 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
204 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 189 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
205 RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
206 RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
207 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 190 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
208 191
209 PSSR = PSSR_RDH | PSSR_PH; 192 PSSR = PSSR_RDH | PSSR_PH;
@@ -302,6 +285,8 @@ static struct platform_device *pxa25x_devices[] __initdata = {
302static struct sys_device pxa25x_sysdev[] = { 285static struct sys_device pxa25x_sysdev[] = {
303 { 286 {
304 .cls = &pxa_irq_sysclass, 287 .cls = &pxa_irq_sysclass,
288 }, {
289 .cls = &pxa_gpio_sysclass,
305 }, 290 },
306}; 291};
307 292
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 343296a710b3..46a951c3e5a0 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -172,11 +172,6 @@ static struct clk pxa27x_clks[] = {
172#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 172#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
173#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 173#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
174 174
175#define RESTORE_GPLEVEL(n) do { \
176 GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
177 GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
178} while (0)
179
180/* 175/*
181 * List of global PXA peripheral registers to preserve. 176 * List of global PXA peripheral registers to preserve.
182 * More ones like CP and general purpose register values are preserved 177 * More ones like CP and general purpose register values are preserved
@@ -184,10 +179,6 @@ static struct clk pxa27x_clks[] = {
184 */ 179 */
185enum { SLEEP_SAVE_START = 0, 180enum { SLEEP_SAVE_START = 0,
186 181
187 SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
188 SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
189 SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
190 SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
191 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, 182 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
192 183
193 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 184 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
@@ -208,10 +199,6 @@ enum { SLEEP_SAVE_START = 0,
208 199
209void pxa27x_cpu_pm_save(unsigned long *sleep_save) 200void pxa27x_cpu_pm_save(unsigned long *sleep_save)
210{ 201{
211 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3);
212 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3);
213 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3);
214 SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3);
215 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); 202 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
216 203
217 SAVE(GAFR0_L); SAVE(GAFR0_U); 204 SAVE(GAFR0_L); SAVE(GAFR0_U);
@@ -225,9 +212,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save)
225 212
226 SAVE(CKEN); 213 SAVE(CKEN);
227 SAVE(PSTR); 214 SAVE(PSTR);
228
229 /* Clear GPIO transition detect bits */
230 GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3;
231} 215}
232 216
233void pxa27x_cpu_pm_restore(unsigned long *sleep_save) 217void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
@@ -236,15 +220,10 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
236 PSPR = 0; 220 PSPR = 0;
237 221
238 /* restore registers */ 222 /* restore registers */
239 RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1);
240 RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3);
241 RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3);
242 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 223 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
243 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 224 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
244 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 225 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
245 RESTORE(GAFR3_L); RESTORE(GAFR3_U); 226 RESTORE(GAFR3_L); RESTORE(GAFR3_U);
246 RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3);
247 RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3);
248 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); 227 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
249 228
250 RESTORE(MDREFR); 229 RESTORE(MDREFR);
@@ -412,6 +391,8 @@ static struct sys_device pxa27x_sysdev[] = {
412 }, { 391 }, {
413 .id = 1, 392 .id = 1,
414 .cls = &pxa_irq_sysclass, 393 .cls = &pxa_irq_sysclass,
394 }, {
395 .cls = &pxa_gpio_sysclass,
415 }, 396 },
416}; 397};
417 398
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 3a7e8ccd70bd..d0b2afd4368a 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -460,6 +460,8 @@ static struct sys_device pxa3xx_sysdev[] = {
460 }, { 460 }, {
461 .id = 1, 461 .id = 1,
462 .cls = &pxa_irq_sysclass, 462 .cls = &pxa_irq_sysclass,
463 }, {
464 .cls = &pxa_gpio_sysclass,
463 }, 465 },
464}; 466};
465 467