diff options
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/cm-x270.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/devices.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/generic.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-pxa/generic.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-pxa/irq.c | 62 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mfp.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pcm027.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/poodle.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 43 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 49 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 99 | ||||
-rw-r--r-- | arch/arm/mach-pxa/sleep.S | 102 | ||||
-rw-r--r-- | arch/arm/mach-pxa/smemc.c | 88 | ||||
-rw-r--r-- | arch/arm/mach-pxa/spitz.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa.c | 1 |
16 files changed, 455 insertions, 74 deletions
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index b5c916c0747d..8604938bd948 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | obj-y += clock.o devices.o generic.o irq.o dma.o time.o | 6 | obj-y += clock.o devices.o generic.o irq.o dma.o time.o |
7 | obj-$(CONFIG_PXA25x) += pxa25x.o | 7 | obj-$(CONFIG_PXA25x) += pxa25x.o |
8 | obj-$(CONFIG_PXA27x) += pxa27x.o | 8 | obj-$(CONFIG_PXA27x) += pxa27x.o |
9 | obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o | 9 | obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o smemc.o |
10 | obj-$(CONFIG_CPU_PXA300) += pxa300.o | 10 | obj-$(CONFIG_CPU_PXA300) += pxa300.o |
11 | obj-$(CONFIG_CPU_PXA320) += pxa320.o | 11 | obj-$(CONFIG_CPU_PXA320) += pxa320.o |
12 | 12 | ||
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 28cfd71c032d..6012177a29a3 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/mach/map.h> | 29 | #include <asm/mach/map.h> |
30 | 30 | ||
31 | #include <asm/arch/pxa-regs.h> | 31 | #include <asm/arch/pxa-regs.h> |
32 | #include <asm/arch/pxa2xx-regs.h> | ||
32 | #include <asm/arch/pxafb.h> | 33 | #include <asm/arch/pxafb.h> |
33 | #include <asm/arch/ohci.h> | 34 | #include <asm/arch/ohci.h> |
34 | #include <asm/arch/mmc.h> | 35 | #include <asm/arch/mmc.h> |
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 50ff453ad370..bfccb80ac8ef 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <asm/arch/mmc.h> | 10 | #include <asm/arch/mmc.h> |
11 | #include <asm/arch/irda.h> | 11 | #include <asm/arch/irda.h> |
12 | #include <asm/arch/i2c.h> | 12 | #include <asm/arch/i2c.h> |
13 | #include <asm/arch/ohci.h> | ||
13 | 14 | ||
14 | #include "devices.h" | 15 | #include "devices.h" |
15 | 16 | ||
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 | |||
233 | static unsigned long saved_gplr[4]; | ||
234 | static unsigned long saved_gpdr[4]; | ||
235 | static unsigned long saved_grer[4]; | ||
236 | static unsigned long saved_gfer[4]; | ||
237 | |||
238 | static 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 | |||
254 | static 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 | |||
274 | struct sysdev_class pxa_gpio_sysclass = { | ||
275 | .name = "gpio", | ||
276 | .suspend = pxa_gpio_suspend, | ||
277 | .resume = pxa_gpio_resume, | ||
278 | }; | ||
279 | |||
280 | static int __init pxa_gpio_init(void) | ||
281 | { | ||
282 | return sysdev_class_register(&pxa_gpio_sysclass); | ||
283 | } | ||
284 | |||
285 | core_initcall(pxa_gpio_init); | ||
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index b30f240a16c7..1a16ad3ecee6 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h | |||
@@ -52,3 +52,6 @@ extern unsigned pxa3xx_get_memclk_frequency_10khz(void); | |||
52 | #define pxa3xx_get_clk_frequency_khz(x) (0) | 52 | #define pxa3xx_get_clk_frequency_khz(x) (0) |
53 | #define pxa3xx_get_memclk_frequency_10khz() (0) | 53 | #define pxa3xx_get_memclk_frequency_10khz() (0) |
54 | #endif | 54 | #endif |
55 | |||
56 | extern struct sysdev_class pxa_irq_sysclass; | ||
57 | extern struct sysdev_class pxa_gpio_sysclass; | ||
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 07acb45b16ea..5a1d5eef10a4 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/sysdev.h> | ||
18 | 19 | ||
19 | #include <asm/hardware.h> | 20 | #include <asm/hardware.h> |
20 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
@@ -321,3 +322,64 @@ void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) | |||
321 | pxa_low_gpio_chip.set_wake = set_wake; | 322 | pxa_low_gpio_chip.set_wake = set_wake; |
322 | pxa_muxed_gpio_chip.set_wake = set_wake; | 323 | pxa_muxed_gpio_chip.set_wake = set_wake; |
323 | } | 324 | } |
325 | |||
326 | #ifdef CONFIG_PM | ||
327 | static unsigned long saved_icmr[2]; | ||
328 | |||
329 | static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | ||
330 | { | ||
331 | switch (dev->id) { | ||
332 | case 0: | ||
333 | saved_icmr[0] = ICMR; | ||
334 | ICMR = 0; | ||
335 | break; | ||
336 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
337 | case 1: | ||
338 | saved_icmr[1] = ICMR2; | ||
339 | ICMR2 = 0; | ||
340 | break; | ||
341 | #endif | ||
342 | default: | ||
343 | return -EINVAL; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int pxa_irq_resume(struct sys_device *dev) | ||
350 | { | ||
351 | switch (dev->id) { | ||
352 | case 0: | ||
353 | ICMR = saved_icmr[0]; | ||
354 | ICLR = 0; | ||
355 | ICCR = 1; | ||
356 | break; | ||
357 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||
358 | case 1: | ||
359 | ICMR2 = saved_icmr[1]; | ||
360 | ICLR2 = 0; | ||
361 | break; | ||
362 | #endif | ||
363 | default: | ||
364 | return -EINVAL; | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | #else | ||
370 | #define pxa_irq_suspend NULL | ||
371 | #define pxa_irq_resume NULL | ||
372 | #endif | ||
373 | |||
374 | struct sysdev_class pxa_irq_sysclass = { | ||
375 | .name = "irq", | ||
376 | .suspend = pxa_irq_suspend, | ||
377 | .resume = pxa_irq_resume, | ||
378 | }; | ||
379 | |||
380 | static int __init pxa_irq_init(void) | ||
381 | { | ||
382 | return sysdev_class_register(&pxa_irq_sysclass); | ||
383 | } | ||
384 | |||
385 | core_initcall(pxa_irq_init); | ||
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c index ec1b2d8f61c4..f5809adce298 100644 --- a/arch/arm/mach-pxa/mfp.c +++ b/arch/arm/mach-pxa/mfp.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/hardware.h> | 22 | #include <asm/hardware.h> |
23 | #include <asm/arch/mfp.h> | 23 | #include <asm/arch/mfp.h> |
24 | #include <asm/arch/mfp-pxa3xx.h> | 24 | #include <asm/arch/mfp-pxa3xx.h> |
25 | #include <asm/arch/pxa3xx-regs.h> | ||
25 | 26 | ||
26 | /* mfp_spin_lock is used to ensure that MFP register configuration | 27 | /* mfp_spin_lock is used to ensure that MFP register configuration |
27 | * (most likely a read-modify-write operation) is atomic, and that | 28 | * (most likely a read-modify-write operation) is atomic, and that |
@@ -223,11 +224,19 @@ static int pxa3xx_mfp_resume(struct sys_device *d) | |||
223 | struct pxa3xx_mfp_pin *p = &mfp_table[pin]; | 224 | struct pxa3xx_mfp_pin *p = &mfp_table[pin]; |
224 | __mfp_config_run(p); | 225 | __mfp_config_run(p); |
225 | } | 226 | } |
227 | |||
228 | /* clear RDH bit when MFP settings are restored | ||
229 | * | ||
230 | * NOTE: the last 3 bits DxS are write-1-to-clear so carefully | ||
231 | * preserve them here in case they will be referenced later | ||
232 | */ | ||
233 | ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); | ||
234 | |||
226 | return 0; | 235 | return 0; |
227 | } | 236 | } |
228 | 237 | ||
229 | static struct sysdev_class mfp_sysclass = { | 238 | static struct sysdev_class mfp_sysclass = { |
230 | set_kset_name("mfp"), | 239 | .name = "mfp", |
231 | .suspend = pxa3xx_mfp_suspend, | 240 | .suspend = pxa3xx_mfp_suspend, |
232 | .resume = pxa3xx_mfp_resume, | 241 | .resume = pxa3xx_mfp_resume, |
233 | }; | 242 | }; |
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index 540c3bba5f9a..c14696b9979d 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
30 | #include <asm/arch/hardware.h> | 30 | #include <asm/arch/hardware.h> |
31 | #include <asm/arch/pxa-regs.h> | 31 | #include <asm/arch/pxa-regs.h> |
32 | #include <asm/arch/pxa2xx-regs.h> | ||
32 | #include <asm/arch/pxa2xx_spi.h> | 33 | #include <asm/arch/pxa2xx_spi.h> |
33 | #include <asm/arch/pcm027.h> | 34 | #include <asm/arch/pcm027.h> |
34 | #include "generic.h" | 35 | #include "generic.h" |
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index dd54496083cb..209eabf0ed3e 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
@@ -164,7 +164,7 @@ static struct resource poodlets_resources[] = { | |||
164 | }, | 164 | }, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static unsigned long poodle_get_hsync_len(void) | 167 | static unsigned long poodle_get_hsync_invperiod(void) |
168 | { | 168 | { |
169 | return 0; | 169 | return 0; |
170 | } | 170 | } |
@@ -174,9 +174,9 @@ static void poodle_null_hsync(void) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | static struct corgits_machinfo poodle_ts_machinfo = { | 176 | static struct corgits_machinfo poodle_ts_machinfo = { |
177 | .get_hsync_len = poodle_get_hsync_len, | 177 | .get_hsync_invperiod = poodle_get_hsync_invperiod, |
178 | .put_hsync = poodle_null_hsync, | 178 | .put_hsync = poodle_null_hsync, |
179 | .wait_hsync = poodle_null_hsync, | 179 | .wait_hsync = poodle_null_hsync, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static struct platform_device poodle_ts_device = { | 182 | static struct platform_device poodle_ts_device = { |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index ddd05bf78e02..599e53fcc2c5 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
24 | #include <linux/sysdev.h> | ||
24 | 25 | ||
25 | #include <asm/hardware.h> | 26 | #include <asm/hardware.h> |
26 | #include <asm/arch/irqs.h> | 27 | #include <asm/arch/irqs.h> |
@@ -141,11 +142,6 @@ static struct clk pxa25x_clks[] = { | |||
141 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 142 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
142 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 143 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
143 | 144 | ||
144 | #define RESTORE_GPLEVEL(n) do { \ | ||
145 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
146 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
147 | } while (0) | ||
148 | |||
149 | /* | 145 | /* |
150 | * List of global PXA peripheral registers to preserve. | 146 | * List of global PXA peripheral registers to preserve. |
151 | * More ones like CP and general purpose register values are preserved | 147 | * More ones like CP and general purpose register values are preserved |
@@ -153,10 +149,6 @@ static struct clk pxa25x_clks[] = { | |||
153 | */ | 149 | */ |
154 | enum { SLEEP_SAVE_START = 0, | 150 | enum { SLEEP_SAVE_START = 0, |
155 | 151 | ||
156 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, | ||
157 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, | ||
158 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, | ||
159 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, | ||
160 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, | 152 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, |
161 | 153 | ||
162 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | 154 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, |
@@ -165,7 +157,6 @@ enum { SLEEP_SAVE_START = 0, | |||
165 | 157 | ||
166 | SLEEP_SAVE_PSTR, | 158 | SLEEP_SAVE_PSTR, |
167 | 159 | ||
168 | SLEEP_SAVE_ICMR, | ||
169 | SLEEP_SAVE_CKEN, | 160 | SLEEP_SAVE_CKEN, |
170 | 161 | ||
171 | SLEEP_SAVE_SIZE | 162 | SLEEP_SAVE_SIZE |
@@ -174,17 +165,12 @@ enum { SLEEP_SAVE_START = 0, | |||
174 | 165 | ||
175 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | 166 | static 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); |
184 | SAVE(GAFR1_L); SAVE(GAFR1_U); | 171 | SAVE(GAFR1_L); SAVE(GAFR1_U); |
185 | SAVE(GAFR2_L); SAVE(GAFR2_U); | 172 | SAVE(GAFR2_L); SAVE(GAFR2_U); |
186 | 173 | ||
187 | SAVE(ICMR); ICMR = 0; | ||
188 | SAVE(CKEN); | 174 | SAVE(CKEN); |
189 | SAVE(PSTR); | 175 | SAVE(PSTR); |
190 | 176 | ||
@@ -198,22 +184,14 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | |||
198 | PSPR = 0; | 184 | PSPR = 0; |
199 | 185 | ||
200 | /* restore registers */ | 186 | /* restore registers */ |
201 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); | ||
202 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); | ||
203 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | 187 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); |
204 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | 188 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); |
205 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | 189 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); |
206 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); | ||
207 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); | ||
208 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | 190 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); |
209 | 191 | ||
210 | PSSR = PSSR_RDH | PSSR_PH; | 192 | PSSR = PSSR_RDH | PSSR_PH; |
211 | 193 | ||
212 | RESTORE(CKEN); | 194 | RESTORE(CKEN); |
213 | |||
214 | ICLR = 0; | ||
215 | ICCR = 1; | ||
216 | RESTORE(ICMR); | ||
217 | RESTORE(PSTR); | 195 | RESTORE(PSTR); |
218 | } | 196 | } |
219 | 197 | ||
@@ -304,9 +282,17 @@ static struct platform_device *pxa25x_devices[] __initdata = { | |||
304 | &pxa25x_device_assp, | 282 | &pxa25x_device_assp, |
305 | }; | 283 | }; |
306 | 284 | ||
285 | static struct sys_device pxa25x_sysdev[] = { | ||
286 | { | ||
287 | .cls = &pxa_irq_sysclass, | ||
288 | }, { | ||
289 | .cls = &pxa_gpio_sysclass, | ||
290 | }, | ||
291 | }; | ||
292 | |||
307 | static int __init pxa25x_init(void) | 293 | static int __init pxa25x_init(void) |
308 | { | 294 | { |
309 | int ret = 0; | 295 | int i, ret = 0; |
310 | 296 | ||
311 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 297 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ |
312 | if (cpu_is_pxa25x()) | 298 | if (cpu_is_pxa25x()) |
@@ -320,9 +306,18 @@ static int __init pxa25x_init(void) | |||
320 | 306 | ||
321 | pxa25x_init_pm(); | 307 | pxa25x_init_pm(); |
322 | 308 | ||
309 | for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) { | ||
310 | ret = sysdev_register(&pxa25x_sysdev[i]); | ||
311 | if (ret) | ||
312 | pr_err("failed to register sysdev[%d]\n", i); | ||
313 | } | ||
314 | |||
323 | ret = platform_add_devices(pxa25x_devices, | 315 | ret = platform_add_devices(pxa25x_devices, |
324 | ARRAY_SIZE(pxa25x_devices)); | 316 | ARRAY_SIZE(pxa25x_devices)); |
317 | if (ret) | ||
318 | return ret; | ||
325 | } | 319 | } |
320 | |||
326 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 321 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ |
327 | if (cpu_is_pxa25x()) | 322 | if (cpu_is_pxa25x()) |
328 | ret = platform_device_register(&pxa_device_hwuart); | 323 | ret = platform_device_register(&pxa_device_hwuart); |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 96cf274ec7cb..46a951c3e5a0 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/sysdev.h> | ||
19 | 20 | ||
20 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
21 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
@@ -171,11 +172,6 @@ static struct clk pxa27x_clks[] = { | |||
171 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 172 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
172 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 173 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
173 | 174 | ||
174 | #define RESTORE_GPLEVEL(n) do { \ | ||
175 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
176 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
177 | } while (0) | ||
178 | |||
179 | /* | 175 | /* |
180 | * List of global PXA peripheral registers to preserve. | 176 | * List of global PXA peripheral registers to preserve. |
181 | * More ones like CP and general purpose register values are preserved | 177 | * More ones like CP and general purpose register values are preserved |
@@ -183,10 +179,6 @@ static struct clk pxa27x_clks[] = { | |||
183 | */ | 179 | */ |
184 | enum { SLEEP_SAVE_START = 0, | 180 | enum { SLEEP_SAVE_START = 0, |
185 | 181 | ||
186 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, | ||
187 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, | ||
188 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, | ||
189 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, | ||
190 | 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, |
191 | 183 | ||
192 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | 184 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, |
@@ -196,7 +188,6 @@ enum { SLEEP_SAVE_START = 0, | |||
196 | 188 | ||
197 | SLEEP_SAVE_PSTR, | 189 | SLEEP_SAVE_PSTR, |
198 | 190 | ||
199 | SLEEP_SAVE_ICMR, | ||
200 | SLEEP_SAVE_CKEN, | 191 | SLEEP_SAVE_CKEN, |
201 | 192 | ||
202 | SLEEP_SAVE_MDREFR, | 193 | SLEEP_SAVE_MDREFR, |
@@ -208,10 +199,6 @@ enum { SLEEP_SAVE_START = 0, | |||
208 | 199 | ||
209 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) | 200 | void 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); |
@@ -223,12 +210,8 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save) | |||
223 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); | 210 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); |
224 | SAVE(PFER); SAVE(PKWR); | 211 | SAVE(PFER); SAVE(PKWR); |
225 | 212 | ||
226 | SAVE(ICMR); ICMR = 0; | ||
227 | SAVE(CKEN); | 213 | SAVE(CKEN); |
228 | SAVE(PSTR); | 214 | SAVE(PSTR); |
229 | |||
230 | /* Clear GPIO transition detect bits */ | ||
231 | GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3; | ||
232 | } | 215 | } |
233 | 216 | ||
234 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | 217 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) |
@@ -237,15 +220,10 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | |||
237 | PSPR = 0; | 220 | PSPR = 0; |
238 | 221 | ||
239 | /* restore registers */ | 222 | /* restore registers */ |
240 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); | ||
241 | RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3); | ||
242 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3); | ||
243 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | 223 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); |
244 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | 224 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); |
245 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | 225 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); |
246 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); | 226 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); |
247 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3); | ||
248 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3); | ||
249 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); | 227 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); |
250 | 228 | ||
251 | RESTORE(MDREFR); | 229 | RESTORE(MDREFR); |
@@ -256,9 +234,6 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | |||
256 | 234 | ||
257 | RESTORE(CKEN); | 235 | RESTORE(CKEN); |
258 | 236 | ||
259 | ICLR = 0; | ||
260 | ICCR = 1; | ||
261 | RESTORE(ICMR); | ||
262 | RESTORE(PSTR); | 237 | RESTORE(PSTR); |
263 | } | 238 | } |
264 | 239 | ||
@@ -409,9 +384,22 @@ static struct platform_device *devices[] __initdata = { | |||
409 | &pxa27x_device_ssp3, | 384 | &pxa27x_device_ssp3, |
410 | }; | 385 | }; |
411 | 386 | ||
387 | static struct sys_device pxa27x_sysdev[] = { | ||
388 | { | ||
389 | .id = 0, | ||
390 | .cls = &pxa_irq_sysclass, | ||
391 | }, { | ||
392 | .id = 1, | ||
393 | .cls = &pxa_irq_sysclass, | ||
394 | }, { | ||
395 | .cls = &pxa_gpio_sysclass, | ||
396 | }, | ||
397 | }; | ||
398 | |||
412 | static int __init pxa27x_init(void) | 399 | static int __init pxa27x_init(void) |
413 | { | 400 | { |
414 | int ret = 0; | 401 | int i, ret = 0; |
402 | |||
415 | if (cpu_is_pxa27x()) { | 403 | if (cpu_is_pxa27x()) { |
416 | clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); | 404 | clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); |
417 | 405 | ||
@@ -420,8 +408,15 @@ static int __init pxa27x_init(void) | |||
420 | 408 | ||
421 | pxa27x_init_pm(); | 409 | pxa27x_init_pm(); |
422 | 410 | ||
411 | for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) { | ||
412 | ret = sysdev_register(&pxa27x_sysdev[i]); | ||
413 | if (ret) | ||
414 | pr_err("failed to register sysdev[%d]\n", i); | ||
415 | } | ||
416 | |||
423 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | 417 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
424 | } | 418 | } |
419 | |||
425 | return ret; | 420 | return ret; |
426 | } | 421 | } |
427 | 422 | ||
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 5cbf057a1b32..e47e67c11afe 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/sysdev.h> | ||
23 | 24 | ||
24 | #include <asm/hardware.h> | 25 | #include <asm/hardware.h> |
25 | #include <asm/arch/pxa3xx-regs.h> | 26 | #include <asm/arch/pxa3xx-regs.h> |
@@ -39,6 +40,7 @@ | |||
39 | #define RO_CLK 60000000 | 40 | #define RO_CLK 60000000 |
40 | 41 | ||
41 | #define ACCR_D0CS (1 << 26) | 42 | #define ACCR_D0CS (1 << 26) |
43 | #define ACCR_PCCE (1 << 11) | ||
42 | 44 | ||
43 | /* crystal frequency to static memory controller multiplier (SMCFS) */ | 45 | /* crystal frequency to static memory controller multiplier (SMCFS) */ |
44 | static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; | 46 | static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; |
@@ -203,7 +205,6 @@ static struct clk pxa3xx_clks[] = { | |||
203 | }; | 205 | }; |
204 | 206 | ||
205 | #ifdef CONFIG_PM | 207 | #ifdef CONFIG_PM |
206 | #define SLEEP_SAVE_SIZE 4 | ||
207 | 208 | ||
208 | #define ISRAM_START 0x5c000000 | 209 | #define ISRAM_START 0x5c000000 |
209 | #define ISRAM_SIZE SZ_256K | 210 | #define ISRAM_SIZE SZ_256K |
@@ -211,25 +212,29 @@ static struct clk pxa3xx_clks[] = { | |||
211 | static void __iomem *sram; | 212 | static void __iomem *sram; |
212 | static unsigned long wakeup_src; | 213 | static unsigned long wakeup_src; |
213 | 214 | ||
214 | static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) | 215 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
215 | { | 216 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
216 | pr_debug("PM: CKENA=%08x CKENB=%08x\n", CKENA, CKENB); | ||
217 | 217 | ||
218 | if (CKENA & (1 << CKEN_USBH)) { | 218 | enum { SLEEP_SAVE_START = 0, |
219 | printk(KERN_ERR "PM: USB host clock not stopped?\n"); | 219 | SLEEP_SAVE_CKENA, |
220 | CKENA &= ~(1 << CKEN_USBH); | 220 | SLEEP_SAVE_CKENB, |
221 | } | 221 | SLEEP_SAVE_ACCR, |
222 | // CKENA |= 1 << (CKEN_ISC & 31); | ||
223 | 222 | ||
224 | /* | 223 | SLEEP_SAVE_SIZE, |
225 | * Low power modes require the HSIO2 clock to be enabled. | 224 | }; |
226 | */ | 225 | |
227 | CKENB |= 1 << (CKEN_HSIO2 & 31); | 226 | static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) |
227 | { | ||
228 | SAVE(CKENA); | ||
229 | SAVE(CKENB); | ||
230 | SAVE(ACCR); | ||
228 | } | 231 | } |
229 | 232 | ||
230 | static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) | 233 | static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) |
231 | { | 234 | { |
232 | CKENB &= ~(1 << (CKEN_HSIO2 & 31)); | 235 | RESTORE(ACCR); |
236 | RESTORE(CKENA); | ||
237 | RESTORE(CKENB); | ||
233 | } | 238 | } |
234 | 239 | ||
235 | /* | 240 | /* |
@@ -265,6 +270,46 @@ static void pxa3xx_cpu_standby(unsigned int pwrmode) | |||
265 | printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR); | 270 | printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR); |
266 | } | 271 | } |
267 | 272 | ||
273 | /* | ||
274 | * NOTE: currently, the OBM (OEM Boot Module) binary comes along with | ||
275 | * PXA3xx development kits assumes that the resuming process continues | ||
276 | * with the address stored within the first 4 bytes of SDRAM. The PSPR | ||
277 | * register is used privately by BootROM and OBM, and _must_ be set to | ||
278 | * 0x5c014000 for the moment. | ||
279 | */ | ||
280 | static void pxa3xx_cpu_pm_suspend(void) | ||
281 | { | ||
282 | volatile unsigned long *p = (volatile void *)0xc0000000; | ||
283 | unsigned long saved_data = *p; | ||
284 | |||
285 | extern void pxa3xx_cpu_suspend(void); | ||
286 | extern void pxa3xx_cpu_resume(void); | ||
287 | |||
288 | /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ | ||
289 | CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); | ||
290 | CKENB |= 1 << (CKEN_HSIO2 & 0x1f); | ||
291 | |||
292 | /* clear and setup wakeup source */ | ||
293 | AD3SR = ~0; | ||
294 | AD3ER = wakeup_src; | ||
295 | ASCR = ASCR; | ||
296 | ARSR = ARSR; | ||
297 | |||
298 | PCFR |= (1u << 13); /* L1_DIS */ | ||
299 | PCFR &= ~((1u << 12) | (1u << 1)); /* L0_EN | SL_ROD */ | ||
300 | |||
301 | PSPR = 0x5c014000; | ||
302 | |||
303 | /* overwrite with the resume address */ | ||
304 | *p = virt_to_phys(pxa3xx_cpu_resume); | ||
305 | |||
306 | pxa3xx_cpu_suspend(); | ||
307 | |||
308 | *p = saved_data; | ||
309 | |||
310 | AD3ER = 0; | ||
311 | } | ||
312 | |||
268 | static void pxa3xx_cpu_pm_enter(suspend_state_t state) | 313 | static void pxa3xx_cpu_pm_enter(suspend_state_t state) |
269 | { | 314 | { |
270 | /* | 315 | /* |
@@ -279,6 +324,7 @@ static void pxa3xx_cpu_pm_enter(suspend_state_t state) | |||
279 | break; | 324 | break; |
280 | 325 | ||
281 | case PM_SUSPEND_MEM: | 326 | case PM_SUSPEND_MEM: |
327 | pxa3xx_cpu_pm_suspend(); | ||
282 | break; | 328 | break; |
283 | } | 329 | } |
284 | } | 330 | } |
@@ -452,9 +498,21 @@ static struct platform_device *devices[] __initdata = { | |||
452 | &pxa3xx_device_ssp4, | 498 | &pxa3xx_device_ssp4, |
453 | }; | 499 | }; |
454 | 500 | ||
501 | static struct sys_device pxa3xx_sysdev[] = { | ||
502 | { | ||
503 | .id = 0, | ||
504 | .cls = &pxa_irq_sysclass, | ||
505 | }, { | ||
506 | .id = 1, | ||
507 | .cls = &pxa_irq_sysclass, | ||
508 | }, { | ||
509 | .cls = &pxa_gpio_sysclass, | ||
510 | }, | ||
511 | }; | ||
512 | |||
455 | static int __init pxa3xx_init(void) | 513 | static int __init pxa3xx_init(void) |
456 | { | 514 | { |
457 | int ret = 0; | 515 | int i, ret = 0; |
458 | 516 | ||
459 | if (cpu_is_pxa3xx()) { | 517 | if (cpu_is_pxa3xx()) { |
460 | clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); | 518 | clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); |
@@ -464,9 +522,16 @@ static int __init pxa3xx_init(void) | |||
464 | 522 | ||
465 | pxa3xx_init_pm(); | 523 | pxa3xx_init_pm(); |
466 | 524 | ||
467 | return platform_add_devices(devices, ARRAY_SIZE(devices)); | 525 | for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) { |
526 | ret = sysdev_register(&pxa3xx_sysdev[i]); | ||
527 | if (ret) | ||
528 | pr_err("failed to register sysdev[%d]\n", i); | ||
529 | } | ||
530 | |||
531 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
468 | } | 532 | } |
469 | return 0; | 533 | |
534 | return ret; | ||
470 | } | 535 | } |
471 | 536 | ||
472 | subsys_initcall(pxa3xx_init); | 537 | subsys_initcall(pxa3xx_init); |
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 14bb4a93ea52..784716eb7fc5 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S | |||
@@ -50,6 +50,108 @@ pxa_cpu_save_sp: | |||
50 | str r0, [r1] | 50 | str r0, [r1] |
51 | ldr pc, [sp], #4 | 51 | ldr pc, [sp], #4 |
52 | 52 | ||
53 | #ifdef CONFIG_PXA3xx | ||
54 | /* | ||
55 | * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4) | ||
56 | * | ||
57 | * NOTE: unfortunately, pxa_cpu_save_cp can not be reused here since | ||
58 | * the auxiliary control register address is different between pxa3xx | ||
59 | * and pxa{25x,27x} | ||
60 | */ | ||
61 | |||
62 | ENTRY(pxa3xx_cpu_suspend) | ||
63 | |||
64 | #ifndef CONFIG_IWMMXT | ||
65 | mra r2, r3, acc0 | ||
66 | #endif | ||
67 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
68 | |||
69 | mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode | ||
70 | mrc p15, 0, r4, c15, c1, 0 @ CP access reg | ||
71 | mrc p15, 0, r5, c13, c0, 0 @ PID | ||
72 | mrc p15, 0, r6, c3, c0, 0 @ domain ID | ||
73 | mrc p15, 0, r7, c2, c0, 0 @ translation table base addr | ||
74 | mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg | ||
75 | mrc p15, 0, r9, c1, c0, 0 @ control reg | ||
76 | |||
77 | bic r3, r3, #2 @ clear frequency change bit | ||
78 | |||
79 | @ store them plus current virtual stack ptr on stack | ||
80 | mov r10, sp | ||
81 | stmfd sp!, {r3 - r10} | ||
82 | |||
83 | @ store physical address of stack pointer | ||
84 | mov r0, sp | ||
85 | bl sleep_phys_sp | ||
86 | ldr r1, =sleep_save_sp | ||
87 | str r0, [r1] | ||
88 | |||
89 | @ clean data cache | ||
90 | bl xsc3_flush_kern_cache_all | ||
91 | |||
92 | mov r0, #0x06 @ S2D3C4 mode | ||
93 | mcr p14, 0, r0, c7, c0, 0 @ enter sleep | ||
94 | |||
95 | 20: b 20b @ waiting for sleep | ||
96 | |||
97 | .data | ||
98 | .align 5 | ||
99 | /* | ||
100 | * pxa3xx_cpu_resume | ||
101 | */ | ||
102 | |||
103 | ENTRY(pxa3xx_cpu_resume) | ||
104 | |||
105 | mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off | ||
106 | msr cpsr_c, r0 | ||
107 | |||
108 | ldr r0, sleep_save_sp @ stack phys addr | ||
109 | ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr | ||
110 | |||
111 | mov r1, #0 | ||
112 | mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB | ||
113 | mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer | ||
114 | mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer | ||
115 | mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs | ||
116 | |||
117 | mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode. | ||
118 | mcr p15, 0, r4, c15, c1, 0 @ CP access reg | ||
119 | mcr p15, 0, r5, c13, c0, 0 @ PID | ||
120 | mcr p15, 0, r6, c3, c0, 0 @ domain ID | ||
121 | mcr p15, 0, r7, c2, c0, 0 @ translation table base addr | ||
122 | mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg | ||
123 | |||
124 | @ temporarily map resume_turn_on_mmu into the page table, | ||
125 | @ otherwise prefetch abort occurs after MMU is turned on | ||
126 | mov r1, r7 | ||
127 | bic r1, r1, #0x00ff | ||
128 | bic r1, r1, #0x3f00 | ||
129 | ldr r2, =0x542e | ||
130 | |||
131 | adr r3, resume_turn_on_mmu | ||
132 | mov r3, r3, lsr #20 | ||
133 | orr r4, r2, r3, lsl #20 | ||
134 | ldr r5, [r1, r3, lsl #2] | ||
135 | str r4, [r1, r3, lsl #2] | ||
136 | |||
137 | @ Mapping page table address in the page table | ||
138 | mov r6, r1, lsr #20 | ||
139 | orr r7, r2, r6, lsl #20 | ||
140 | ldr r8, [r1, r6, lsl #2] | ||
141 | str r7, [r1, r6, lsl #2] | ||
142 | |||
143 | ldr r2, =pxa3xx_resume_after_mmu @ absolute virtual address | ||
144 | b resume_turn_on_mmu @ cache align execution | ||
145 | |||
146 | .text | ||
147 | pxa3xx_resume_after_mmu: | ||
148 | /* restore the temporary mapping */ | ||
149 | str r5, [r1, r3, lsl #2] | ||
150 | str r8, [r1, r6, lsl #2] | ||
151 | b resume_after_mmu | ||
152 | |||
153 | #endif /* CONFIG_PXA3xx */ | ||
154 | |||
53 | #ifdef CONFIG_PXA27x | 155 | #ifdef CONFIG_PXA27x |
54 | /* | 156 | /* |
55 | * pxa27x_cpu_suspend() | 157 | * pxa27x_cpu_suspend() |
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c new file mode 100644 index 000000000000..ad346addc028 --- /dev/null +++ b/arch/arm/mach-pxa/smemc.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * Static Memory Controller | ||
3 | */ | ||
4 | |||
5 | #include <linux/module.h> | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/io.h> | ||
9 | #include <linux/sysdev.h> | ||
10 | |||
11 | #define SMEMC_PHYS_BASE (0x4A000000) | ||
12 | #define SMEMC_PHYS_SIZE (0x90) | ||
13 | |||
14 | #define MSC0 (0x08) /* Static Memory Controller Register 0 */ | ||
15 | #define MSC1 (0x0C) /* Static Memory Controller Register 1 */ | ||
16 | #define SXCNFG (0x1C) /* Synchronous Static Memory Control Register */ | ||
17 | #define MEMCLKCFG (0x68) /* Clock Configuration */ | ||
18 | #define CSADRCFG0 (0x80) /* Address Configuration Register for CS0 */ | ||
19 | #define CSADRCFG1 (0x84) /* Address Configuration Register for CS1 */ | ||
20 | #define CSADRCFG2 (0x88) /* Address Configuration Register for CS2 */ | ||
21 | #define CSADRCFG3 (0x8C) /* Address Configuration Register for CS3 */ | ||
22 | |||
23 | #ifdef CONFIG_PM | ||
24 | static void __iomem *smemc_mmio_base; | ||
25 | |||
26 | static unsigned long msc[2]; | ||
27 | static unsigned long sxcnfg, memclkcfg; | ||
28 | static unsigned long csadrcfg[4]; | ||
29 | |||
30 | static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state) | ||
31 | { | ||
32 | msc[0] = __raw_readl(smemc_mmio_base + MSC0); | ||
33 | msc[1] = __raw_readl(smemc_mmio_base + MSC1); | ||
34 | sxcnfg = __raw_readl(smemc_mmio_base + SXCNFG); | ||
35 | memclkcfg = __raw_readl(smemc_mmio_base + MEMCLKCFG); | ||
36 | csadrcfg[0] = __raw_readl(smemc_mmio_base + CSADRCFG0); | ||
37 | csadrcfg[1] = __raw_readl(smemc_mmio_base + CSADRCFG1); | ||
38 | csadrcfg[2] = __raw_readl(smemc_mmio_base + CSADRCFG2); | ||
39 | csadrcfg[3] = __raw_readl(smemc_mmio_base + CSADRCFG3); | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int pxa3xx_smemc_resume(struct sys_device *dev) | ||
45 | { | ||
46 | __raw_writel(msc[0], smemc_mmio_base + MSC0); | ||
47 | __raw_writel(msc[1], smemc_mmio_base + MSC1); | ||
48 | __raw_writel(sxcnfg, smemc_mmio_base + SXCNFG); | ||
49 | __raw_writel(memclkcfg, smemc_mmio_base + MEMCLKCFG); | ||
50 | __raw_writel(csadrcfg[0], smemc_mmio_base + CSADRCFG0); | ||
51 | __raw_writel(csadrcfg[1], smemc_mmio_base + CSADRCFG1); | ||
52 | __raw_writel(csadrcfg[2], smemc_mmio_base + CSADRCFG2); | ||
53 | __raw_writel(csadrcfg[3], smemc_mmio_base + CSADRCFG3); | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static struct sysdev_class smemc_sysclass = { | ||
59 | .name = "smemc", | ||
60 | .suspend = pxa3xx_smemc_suspend, | ||
61 | .resume = pxa3xx_smemc_resume, | ||
62 | }; | ||
63 | |||
64 | static struct sys_device smemc_sysdev = { | ||
65 | .id = 0, | ||
66 | .cls = &smemc_sysclass, | ||
67 | }; | ||
68 | |||
69 | static int __init smemc_init(void) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | |||
73 | if (cpu_is_pxa3xx()) { | ||
74 | smemc_mmio_base = ioremap(SMEMC_PHYS_BASE, SMEMC_PHYS_SIZE); | ||
75 | if (smemc_mmio_base == NULL) | ||
76 | return -ENODEV; | ||
77 | |||
78 | ret = sysdev_class_register(&smemc_sysclass); | ||
79 | if (ret) | ||
80 | return ret; | ||
81 | |||
82 | ret = sysdev_register(&smemc_sysdev); | ||
83 | } | ||
84 | |||
85 | return ret; | ||
86 | } | ||
87 | subsys_initcall(smemc_init); | ||
88 | #endif | ||
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 5078edeadf96..9e7773fca01c 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
37 | 37 | ||
38 | #include <asm/arch/pxa-regs.h> | 38 | #include <asm/arch/pxa-regs.h> |
39 | #include <asm/arch/pxa2xx-regs.h> | ||
39 | #include <asm/arch/irda.h> | 40 | #include <asm/arch/irda.h> |
40 | #include <asm/arch/mmc.h> | 41 | #include <asm/arch/mmc.h> |
41 | #include <asm/arch/ohci.h> | 42 | #include <asm/arch/ohci.h> |
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 1a9c844ac7eb..9b26fa5edad6 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/arch/pxa-regs.h> | 31 | #include <asm/arch/pxa-regs.h> |
32 | #include <asm/arch/pxa2xx-regs.h> | ||
32 | #include <asm/arch/irda.h> | 33 | #include <asm/arch/irda.h> |
33 | #include <asm/arch/mmc.h> | 34 | #include <asm/arch/mmc.h> |
34 | #include <asm/arch/udc.h> | 35 | #include <asm/arch/udc.h> |