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