[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>
This commit is contained in:
eric miao 2008-01-28 23:00:02 +00:00 committed by Russell King
parent cd5604d561
commit c016550490
5 changed files with 122 additions and 16 deletions

View File

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

View File

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

View File

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

View File

@ -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;
}

View File

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