mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +00:00
[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:
parent
cd5604d561
commit
c016550490
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user