aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric miao <eric.miao@marvell.com>2008-01-28 18:00:02 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-02-04 08:17:33 -0500
commitc016550490687c6bdbcdf06c7b4d874b6c7c6e4e (patch)
treed2b31c1d89c72417d050343caa6a6a5161b6d02f
parentcd5604d5618a802e4ed047eb8b1515edc5fc49b5 (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.h2
-rw-r--r--arch/arm/mach-pxa/irq.c62
-rw-r--r--arch/arm/mach-pxa/pxa25x.c24
-rw-r--r--arch/arm/mach-pxa/pxa27x.c26
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c24
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
56extern 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
327static unsigned long saved_icmr[2];
328
329static 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
349static 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
374struct sysdev_class pxa_irq_sysclass = {
375 .name = "irq",
376 .suspend = pxa_irq_suspend,
377 .resume = pxa_irq_resume,
378};
379
380static int __init pxa_irq_init(void)
381{
382 return sysdev_class_register(&pxa_irq_sysclass);
383}
384
385core_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
302static struct sys_device pxa25x_sysdev[] = {
303 {
304 .cls = &pxa_irq_sysclass,
305 },
306};
307
307static int __init pxa25x_init(void) 308static 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
408static 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
412static int __init pxa27x_init(void) 418static 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
456static 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
455static int __init pxa3xx_init(void) 466static 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
472subsys_initcall(pxa3xx_init); 490subsys_initcall(pxa3xx_init);