diff options
Diffstat (limited to 'arch/arm')
-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 b30f240a16c..367b67923e1 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); #define pxa3xx_get_clk_frequency_khz(x) (0) #define pxa3xx_get_memclk_frequency_10khz() (0) #endif + +extern struct sysdev_class pxa_irq_sysclass; diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 07acb45b16e..5a1d5eef10a 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> +#include <linux/sysdev.h> #include <asm/hardware.h> #include <asm/irq.h> @@ -321,3 +322,64 @@ void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) pxa_low_gpio_chip.set_wake = set_wake; pxa_muxed_gpio_chip.set_wake = set_wake; } + +#ifdef CONFIG_PM +static unsigned long saved_icmr[2]; + +static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) +{ + switch (dev->id) { + case 0: + saved_icmr[0] = ICMR; + ICMR = 0; + break; +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) + case 1: + saved_icmr[1] = ICMR2; + ICMR2 = 0; + break; +#endif + default: + return -EINVAL; + } + + return 0; +} + +static int pxa_irq_resume(struct sys_device *dev) +{ + switch (dev->id) { + case 0: + ICMR = saved_icmr[0]; + ICLR = 0; + ICCR = 1; + break; +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) + case 1: + ICMR2 = saved_icmr[1]; + ICLR2 = 0; + break; +#endif + default: + return -EINVAL; + } + + return 0; +} +#else +#define pxa_irq_suspend NULL +#define pxa_irq_resume NULL +#endif + +struct sysdev_class pxa_irq_sysclass = { + .name = "irq", + .suspend = pxa_irq_suspend, + .resume = pxa_irq_resume, +}; + +static int __init pxa_irq_init(void) +{ + return sysdev_class_register(&pxa_irq_sysclass); +} + +core_initcall(pxa_irq_init); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index ddd05bf78e0..797635eec6b 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/suspend.h> +#include <linux/sysdev.h> #include <asm/hardware.h> #include <asm/arch/irqs.h> @@ -165,7 +166,6 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_PSTR, - SLEEP_SAVE_ICMR, SLEEP_SAVE_CKEN, SLEEP_SAVE_SIZE @@ -184,7 +184,6 @@ static void pxa25x_cpu_pm_save(unsigned long *sleep_save) SAVE(GAFR1_L); SAVE(GAFR1_U); SAVE(GAFR2_L); SAVE(GAFR2_U); - SAVE(ICMR); ICMR = 0; SAVE(CKEN); SAVE(PSTR); @@ -210,10 +209,6 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) PSSR = PSSR_RDH | PSSR_PH; RESTORE(CKEN); - - ICLR = 0; - ICCR = 1; - RESTORE(ICMR); RESTORE(PSTR); } @@ -304,9 +299,15 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_assp, }; +static struct sys_device pxa25x_sysdev[] = { + { + .cls = &pxa_irq_sysclass, + }, +}; + static int __init pxa25x_init(void) { - int ret = 0; + int i, ret = 0; /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ if (cpu_is_pxa25x()) @@ -320,9 +321,18 @@ static int __init pxa25x_init(void) pxa25x_init_pm(); + for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) { + ret = sysdev_register(&pxa25x_sysdev[i]); + if (ret) + pr_err("failed to register sysdev[%d]\n", i); + } + ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); + if (ret) + return ret; } + /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ if (cpu_is_pxa25x()) ret = platform_device_register(&pxa_device_hwuart); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 96cf274ec7c..343296a710b 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <linux/suspend.h> #include <linux/platform_device.h> +#include <linux/sysdev.h> #include <asm/hardware.h> #include <asm/irq.h> @@ -196,7 +197,6 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_PSTR, - SLEEP_SAVE_ICMR, SLEEP_SAVE_CKEN, SLEEP_SAVE_MDREFR, @@ -223,7 +223,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save) SAVE(PWER); SAVE(PCFR); SAVE(PRER); SAVE(PFER); SAVE(PKWR); - SAVE(ICMR); ICMR = 0; SAVE(CKEN); SAVE(PSTR); @@ -256,9 +255,6 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) RESTORE(CKEN); - ICLR = 0; - ICCR = 1; - RESTORE(ICMR); RESTORE(PSTR); } @@ -409,9 +405,20 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp3, }; +static struct sys_device pxa27x_sysdev[] = { + { + .id = 0, + .cls = &pxa_irq_sysclass, + }, { + .id = 1, + .cls = &pxa_irq_sysclass, + }, +}; + static int __init pxa27x_init(void) { - int ret = 0; + int i, ret = 0; + if (cpu_is_pxa27x()) { clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); @@ -420,8 +427,15 @@ static int __init pxa27x_init(void) pxa27x_init_pm(); + for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) { + ret = sysdev_register(&pxa27x_sysdev[i]); + if (ret) + pr_err("failed to register sysdev[%d]\n", i); + } + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } + return ret; } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 5cbf057a1b3..3a7e8ccd70b 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -20,6 +20,7 @@ #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/io.h> +#include <linux/sysdev.h> #include <asm/hardware.h> #include <asm/arch/pxa3xx-regs.h> @@ -452,9 +453,19 @@ static struct platform_device *devices[] __initdata = { &pxa3xx_device_ssp4, }; +static struct sys_device pxa3xx_sysdev[] = { + { + .id = 0, + .cls = &pxa_irq_sysclass, + }, { + .id = 1, + .cls = &pxa_irq_sysclass, + }, +}; + static int __init pxa3xx_init(void) { - int ret = 0; + int i, ret = 0; if (cpu_is_pxa3xx()) { clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); @@ -464,9 +475,16 @@ static int __init pxa3xx_init(void) pxa3xx_init_pm(); - return platform_add_devices(devices, ARRAY_SIZE(devices)); + for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) { + ret = sysdev_register(&pxa3xx_sysdev[i]); + if (ret) + pr_err("failed to register sysdev[%d]\n", i); + } + + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } - return 0; + + return ret; } subsys_initcall(pxa3xx_init); |