diff options
author | eric miao <eric.miao@marvell.com> | 2008-01-28 18:00:02 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-02-04 08:17:33 -0500 |
commit | c016550490687c6bdbcdf06c7b4d874b6c7c6e4e (patch) | |
tree | d2b31c1d89c72417d050343caa6a6a5161b6d02f | |
parent | cd5604d5618a802e4ed047eb8b1515edc5fc49b5 (diff) |
[ARM] pxa: introduce sysdev for IRQ register saving/restoring
Signed-off-by: eric miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mach-pxa/generic.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/irq.c | 62 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 24 |
5 files changed, 122 insertions, 16 deletions
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index b30f240a16c7..367b67923e11 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h | |||
@@ -52,3 +52,5 @@ 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; | ||
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/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index ddd05bf78e02..797635eec6b6 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> |
@@ -165,7 +166,6 @@ enum { SLEEP_SAVE_START = 0, | |||
165 | 166 | ||
166 | SLEEP_SAVE_PSTR, | 167 | SLEEP_SAVE_PSTR, |
167 | 168 | ||
168 | SLEEP_SAVE_ICMR, | ||
169 | SLEEP_SAVE_CKEN, | 169 | SLEEP_SAVE_CKEN, |
170 | 170 | ||
171 | SLEEP_SAVE_SIZE | 171 | SLEEP_SAVE_SIZE |
@@ -184,7 +184,6 @@ static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | |||
184 | SAVE(GAFR1_L); SAVE(GAFR1_U); | 184 | SAVE(GAFR1_L); SAVE(GAFR1_U); |
185 | SAVE(GAFR2_L); SAVE(GAFR2_U); | 185 | SAVE(GAFR2_L); SAVE(GAFR2_U); |
186 | 186 | ||
187 | SAVE(ICMR); ICMR = 0; | ||
188 | SAVE(CKEN); | 187 | SAVE(CKEN); |
189 | SAVE(PSTR); | 188 | SAVE(PSTR); |
190 | 189 | ||
@@ -210,10 +209,6 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | |||
210 | PSSR = PSSR_RDH | PSSR_PH; | 209 | PSSR = PSSR_RDH | PSSR_PH; |
211 | 210 | ||
212 | RESTORE(CKEN); | 211 | RESTORE(CKEN); |
213 | |||
214 | ICLR = 0; | ||
215 | ICCR = 1; | ||
216 | RESTORE(ICMR); | ||
217 | RESTORE(PSTR); | 212 | RESTORE(PSTR); |
218 | } | 213 | } |
219 | 214 | ||
@@ -304,9 +299,15 @@ static struct platform_device *pxa25x_devices[] __initdata = { | |||
304 | &pxa25x_device_assp, | 299 | &pxa25x_device_assp, |
305 | }; | 300 | }; |
306 | 301 | ||
302 | static struct sys_device pxa25x_sysdev[] = { | ||
303 | { | ||
304 | .cls = &pxa_irq_sysclass, | ||
305 | }, | ||
306 | }; | ||
307 | |||
307 | static int __init pxa25x_init(void) | 308 | static int __init pxa25x_init(void) |
308 | { | 309 | { |
309 | int ret = 0; | 310 | int i, ret = 0; |
310 | 311 | ||
311 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 312 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ |
312 | if (cpu_is_pxa25x()) | 313 | if (cpu_is_pxa25x()) |
@@ -320,9 +321,18 @@ static int __init pxa25x_init(void) | |||
320 | 321 | ||
321 | pxa25x_init_pm(); | 322 | pxa25x_init_pm(); |
322 | 323 | ||
324 | for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) { | ||
325 | ret = sysdev_register(&pxa25x_sysdev[i]); | ||
326 | if (ret) | ||
327 | pr_err("failed to register sysdev[%d]\n", i); | ||
328 | } | ||
329 | |||
323 | ret = platform_add_devices(pxa25x_devices, | 330 | ret = platform_add_devices(pxa25x_devices, |
324 | ARRAY_SIZE(pxa25x_devices)); | 331 | ARRAY_SIZE(pxa25x_devices)); |
332 | if (ret) | ||
333 | return ret; | ||
325 | } | 334 | } |
335 | |||
326 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ | 336 | /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ |
327 | if (cpu_is_pxa25x()) | 337 | if (cpu_is_pxa25x()) |
328 | ret = platform_device_register(&pxa_device_hwuart); | 338 | 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..343296a710b3 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> |
@@ -196,7 +197,6 @@ enum { SLEEP_SAVE_START = 0, | |||
196 | 197 | ||
197 | SLEEP_SAVE_PSTR, | 198 | SLEEP_SAVE_PSTR, |
198 | 199 | ||
199 | SLEEP_SAVE_ICMR, | ||
200 | SLEEP_SAVE_CKEN, | 200 | SLEEP_SAVE_CKEN, |
201 | 201 | ||
202 | SLEEP_SAVE_MDREFR, | 202 | SLEEP_SAVE_MDREFR, |
@@ -223,7 +223,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save) | |||
223 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); | 223 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); |
224 | SAVE(PFER); SAVE(PKWR); | 224 | SAVE(PFER); SAVE(PKWR); |
225 | 225 | ||
226 | SAVE(ICMR); ICMR = 0; | ||
227 | SAVE(CKEN); | 226 | SAVE(CKEN); |
228 | SAVE(PSTR); | 227 | SAVE(PSTR); |
229 | 228 | ||
@@ -256,9 +255,6 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | |||
256 | 255 | ||
257 | RESTORE(CKEN); | 256 | RESTORE(CKEN); |
258 | 257 | ||
259 | ICLR = 0; | ||
260 | ICCR = 1; | ||
261 | RESTORE(ICMR); | ||
262 | RESTORE(PSTR); | 258 | RESTORE(PSTR); |
263 | } | 259 | } |
264 | 260 | ||
@@ -409,9 +405,20 @@ static struct platform_device *devices[] __initdata = { | |||
409 | &pxa27x_device_ssp3, | 405 | &pxa27x_device_ssp3, |
410 | }; | 406 | }; |
411 | 407 | ||
408 | static struct sys_device pxa27x_sysdev[] = { | ||
409 | { | ||
410 | .id = 0, | ||
411 | .cls = &pxa_irq_sysclass, | ||
412 | }, { | ||
413 | .id = 1, | ||
414 | .cls = &pxa_irq_sysclass, | ||
415 | }, | ||
416 | }; | ||
417 | |||
412 | static int __init pxa27x_init(void) | 418 | static int __init pxa27x_init(void) |
413 | { | 419 | { |
414 | int ret = 0; | 420 | int i, ret = 0; |
421 | |||
415 | if (cpu_is_pxa27x()) { | 422 | if (cpu_is_pxa27x()) { |
416 | clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); | 423 | clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); |
417 | 424 | ||
@@ -420,8 +427,15 @@ static int __init pxa27x_init(void) | |||
420 | 427 | ||
421 | pxa27x_init_pm(); | 428 | pxa27x_init_pm(); |
422 | 429 | ||
430 | for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) { | ||
431 | ret = sysdev_register(&pxa27x_sysdev[i]); | ||
432 | if (ret) | ||
433 | pr_err("failed to register sysdev[%d]\n", i); | ||
434 | } | ||
435 | |||
423 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | 436 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
424 | } | 437 | } |
438 | |||
425 | return ret; | 439 | return ret; |
426 | } | 440 | } |
427 | 441 | ||
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 5cbf057a1b32..3a7e8ccd70bd 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> |
@@ -452,9 +453,19 @@ static struct platform_device *devices[] __initdata = { | |||
452 | &pxa3xx_device_ssp4, | 453 | &pxa3xx_device_ssp4, |
453 | }; | 454 | }; |
454 | 455 | ||
456 | static struct sys_device pxa3xx_sysdev[] = { | ||
457 | { | ||
458 | .id = 0, | ||
459 | .cls = &pxa_irq_sysclass, | ||
460 | }, { | ||
461 | .id = 1, | ||
462 | .cls = &pxa_irq_sysclass, | ||
463 | }, | ||
464 | }; | ||
465 | |||
455 | static int __init pxa3xx_init(void) | 466 | static int __init pxa3xx_init(void) |
456 | { | 467 | { |
457 | int ret = 0; | 468 | int i, ret = 0; |
458 | 469 | ||
459 | if (cpu_is_pxa3xx()) { | 470 | if (cpu_is_pxa3xx()) { |
460 | clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); | 471 | clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); |
@@ -464,9 +475,16 @@ static int __init pxa3xx_init(void) | |||
464 | 475 | ||
465 | pxa3xx_init_pm(); | 476 | pxa3xx_init_pm(); |
466 | 477 | ||
467 | return platform_add_devices(devices, ARRAY_SIZE(devices)); | 478 | for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) { |
479 | ret = sysdev_register(&pxa3xx_sysdev[i]); | ||
480 | if (ret) | ||
481 | pr_err("failed to register sysdev[%d]\n", i); | ||
482 | } | ||
483 | |||
484 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
468 | } | 485 | } |
469 | return 0; | 486 | |
487 | return ret; | ||
470 | } | 488 | } |
471 | 489 | ||
472 | subsys_initcall(pxa3xx_init); | 490 | subsys_initcall(pxa3xx_init); |