summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreric miao <eric.miao@marvell.com>2008-01-28 23:00:02 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-02-04 13:17:33 +0000
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 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);