提交 16dfdbf0 编写于 作者: E eric miao 提交者: Russell King

[ARM] pxa: introduce sysdev for GPIO register saving/restoring

Signed-off-by: Neric miao <eric.miao@marvell.com>
Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
上级 c0165504
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/sysdev.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -226,3 +227,59 @@ void __init pxa_map_io(void) ...@@ -226,3 +227,59 @@ void __init pxa_map_io(void)
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
get_clk_frequency_khz(1); get_clk_frequency_khz(1);
} }
#ifdef CONFIG_PM
static unsigned long saved_gplr[4];
static unsigned long saved_gpdr[4];
static unsigned long saved_grer[4];
static unsigned long saved_gfer[4];
static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
{
int i, gpio;
for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
saved_gplr[i] = GPLR(gpio);
saved_gpdr[i] = GPDR(gpio);
saved_grer[i] = GRER(gpio);
saved_gfer[i] = GFER(gpio);
/* Clear GPIO transition detect bits */
GEDR(gpio) = GEDR(gpio);
}
return 0;
}
static int pxa_gpio_resume(struct sys_device *dev)
{
int i, gpio;
for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
/* restore level with set/clear */
GPSR(gpio) = saved_gplr[i];
GPCR(gpio) = ~saved_gplr[i];
GRER(gpio) = saved_grer[i];
GFER(gpio) = saved_gfer[i];
GPDR(gpio) = saved_gpdr[i];
}
return 0;
}
#else
#define pxa_gpio_suspend NULL
#define pxa_gpio_resume NULL
#endif
struct sysdev_class pxa_gpio_sysclass = {
.name = "gpio",
.suspend = pxa_gpio_suspend,
.resume = pxa_gpio_resume,
};
static int __init pxa_gpio_init(void)
{
return sysdev_class_register(&pxa_gpio_sysclass);
}
core_initcall(pxa_gpio_init);
...@@ -54,3 +54,4 @@ extern unsigned pxa3xx_get_memclk_frequency_10khz(void); ...@@ -54,3 +54,4 @@ extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
#endif #endif
extern struct sysdev_class pxa_irq_sysclass; extern struct sysdev_class pxa_irq_sysclass;
extern struct sysdev_class pxa_gpio_sysclass;
...@@ -142,11 +142,6 @@ static struct clk pxa25x_clks[] = { ...@@ -142,11 +142,6 @@ static struct clk pxa25x_clks[] = {
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
#define RESTORE_GPLEVEL(n) do { \
GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
} while (0)
/* /*
* List of global PXA peripheral registers to preserve. * List of global PXA peripheral registers to preserve.
* More ones like CP and general purpose register values are preserved * More ones like CP and general purpose register values are preserved
...@@ -154,10 +149,6 @@ static struct clk pxa25x_clks[] = { ...@@ -154,10 +149,6 @@ static struct clk pxa25x_clks[] = {
*/ */
enum { SLEEP_SAVE_START = 0, enum { SLEEP_SAVE_START = 0,
SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2,
SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
...@@ -174,10 +165,6 @@ enum { SLEEP_SAVE_START = 0, ...@@ -174,10 +165,6 @@ enum { SLEEP_SAVE_START = 0,
static void pxa25x_cpu_pm_save(unsigned long *sleep_save) static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
{ {
SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
SAVE(GAFR0_L); SAVE(GAFR0_U); SAVE(GAFR0_L); SAVE(GAFR0_U);
...@@ -197,13 +184,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) ...@@ -197,13 +184,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
PSPR = 0; PSPR = 0;
/* restore registers */ /* restore registers */
RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
RESTORE(GAFR0_L); RESTORE(GAFR0_U); RESTORE(GAFR0_L); RESTORE(GAFR0_U);
RESTORE(GAFR1_L); RESTORE(GAFR1_U); RESTORE(GAFR1_L); RESTORE(GAFR1_U);
RESTORE(GAFR2_L); RESTORE(GAFR2_U); RESTORE(GAFR2_L); RESTORE(GAFR2_U);
RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
PSSR = PSSR_RDH | PSSR_PH; PSSR = PSSR_RDH | PSSR_PH;
...@@ -302,6 +285,8 @@ static struct platform_device *pxa25x_devices[] __initdata = { ...@@ -302,6 +285,8 @@ static struct platform_device *pxa25x_devices[] __initdata = {
static struct sys_device pxa25x_sysdev[] = { static struct sys_device pxa25x_sysdev[] = {
{ {
.cls = &pxa_irq_sysclass, .cls = &pxa_irq_sysclass,
}, {
.cls = &pxa_gpio_sysclass,
}, },
}; };
......
...@@ -172,11 +172,6 @@ static struct clk pxa27x_clks[] = { ...@@ -172,11 +172,6 @@ static struct clk pxa27x_clks[] = {
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
#define RESTORE_GPLEVEL(n) do { \
GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
} while (0)
/* /*
* List of global PXA peripheral registers to preserve. * List of global PXA peripheral registers to preserve.
* More ones like CP and general purpose register values are preserved * More ones like CP and general purpose register values are preserved
...@@ -184,10 +179,6 @@ static struct clk pxa27x_clks[] = { ...@@ -184,10 +179,6 @@ static struct clk pxa27x_clks[] = {
*/ */
enum { SLEEP_SAVE_START = 0, enum { SLEEP_SAVE_START = 0,
SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
...@@ -208,10 +199,6 @@ enum { SLEEP_SAVE_START = 0, ...@@ -208,10 +199,6 @@ enum { SLEEP_SAVE_START = 0,
void pxa27x_cpu_pm_save(unsigned long *sleep_save) void pxa27x_cpu_pm_save(unsigned long *sleep_save)
{ {
SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3);
SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3);
SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3);
SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3);
SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
SAVE(GAFR0_L); SAVE(GAFR0_U); SAVE(GAFR0_L); SAVE(GAFR0_U);
...@@ -225,9 +212,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save) ...@@ -225,9 +212,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save)
SAVE(CKEN); SAVE(CKEN);
SAVE(PSTR); SAVE(PSTR);
/* Clear GPIO transition detect bits */
GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3;
} }
void pxa27x_cpu_pm_restore(unsigned long *sleep_save) void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
...@@ -236,15 +220,10 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) ...@@ -236,15 +220,10 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
PSPR = 0; PSPR = 0;
/* restore registers */ /* restore registers */
RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1);
RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3);
RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3);
RESTORE(GAFR0_L); RESTORE(GAFR0_U); RESTORE(GAFR0_L); RESTORE(GAFR0_U);
RESTORE(GAFR1_L); RESTORE(GAFR1_U); RESTORE(GAFR1_L); RESTORE(GAFR1_U);
RESTORE(GAFR2_L); RESTORE(GAFR2_U); RESTORE(GAFR2_L); RESTORE(GAFR2_U);
RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE(GAFR3_L); RESTORE(GAFR3_U);
RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3);
RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3);
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
RESTORE(MDREFR); RESTORE(MDREFR);
...@@ -412,6 +391,8 @@ static struct sys_device pxa27x_sysdev[] = { ...@@ -412,6 +391,8 @@ static struct sys_device pxa27x_sysdev[] = {
}, { }, {
.id = 1, .id = 1,
.cls = &pxa_irq_sysclass, .cls = &pxa_irq_sysclass,
}, {
.cls = &pxa_gpio_sysclass,
}, },
}; };
......
...@@ -460,6 +460,8 @@ static struct sys_device pxa3xx_sysdev[] = { ...@@ -460,6 +460,8 @@ static struct sys_device pxa3xx_sysdev[] = {
}, { }, {
.id = 1, .id = 1,
.cls = &pxa_irq_sysclass, .cls = &pxa_irq_sysclass,
}, {
.cls = &pxa_gpio_sysclass,
}, },
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册