diff options
| author | eric miao <eric.miao@marvell.com> | 2008-01-28 18:00:02 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-02-04 08:17:33 -0500 |
| commit | 16dfdbf038706c12c56f327d14c6b901edc376a3 (patch) | |
| tree | 1f761ae7ff1c4ba837d24c69521d5cbe0b2d7e72 | |
| parent | c016550490687c6bdbcdf06c7b4d874b6c7c6e4e (diff) | |
[ARM] pxa: introduce sysdev for GPIO 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.c | 57 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/generic.h | 1 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 19 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 23 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 2 |
5 files changed, 64 insertions, 38 deletions
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 698aeec52961..76970598f550 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/ioport.h> | 23 | #include <linux/ioport.h> |
| 24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
| 25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
| 26 | #include <linux/sysdev.h> | ||
| 26 | 27 | ||
| 27 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
| 28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
| @@ -226,3 +227,59 @@ void __init pxa_map_io(void) | |||
| 226 | iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); | 227 | iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); |
| 227 | get_clk_frequency_khz(1); | 228 | get_clk_frequency_khz(1); |
| 228 | } | 229 | } |
| 230 | |||
| 231 | #ifdef CONFIG_PM | ||
| 232 | |||
| 233 | static unsigned long saved_gplr[4]; | ||
| 234 | static unsigned long saved_gpdr[4]; | ||
| 235 | static unsigned long saved_grer[4]; | ||
| 236 | static unsigned long saved_gfer[4]; | ||
| 237 | |||
| 238 | static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state) | ||
| 239 | { | ||
| 240 | int i, gpio; | ||
| 241 | |||
| 242 | for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { | ||
| 243 | saved_gplr[i] = GPLR(gpio); | ||
| 244 | saved_gpdr[i] = GPDR(gpio); | ||
| 245 | saved_grer[i] = GRER(gpio); | ||
| 246 | saved_gfer[i] = GFER(gpio); | ||
| 247 | |||
| 248 | /* Clear GPIO transition detect bits */ | ||
| 249 | GEDR(gpio) = GEDR(gpio); | ||
| 250 | } | ||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int pxa_gpio_resume(struct sys_device *dev) | ||
| 255 | { | ||
| 256 | int i, gpio; | ||
| 257 | |||
| 258 | for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { | ||
| 259 | /* restore level with set/clear */ | ||
| 260 | GPSR(gpio) = saved_gplr[i]; | ||
| 261 | GPCR(gpio) = ~saved_gplr[i]; | ||
| 262 | |||
| 263 | GRER(gpio) = saved_grer[i]; | ||
| 264 | GFER(gpio) = saved_gfer[i]; | ||
| 265 | GPDR(gpio) = saved_gpdr[i]; | ||
| 266 | } | ||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | #else | ||
| 270 | #define pxa_gpio_suspend NULL | ||
| 271 | #define pxa_gpio_resume NULL | ||
| 272 | #endif | ||
| 273 | |||
| 274 | struct sysdev_class pxa_gpio_sysclass = { | ||
| 275 | .name = "gpio", | ||
| 276 | .suspend = pxa_gpio_suspend, | ||
| 277 | .resume = pxa_gpio_resume, | ||
| 278 | }; | ||
| 279 | |||
| 280 | static int __init pxa_gpio_init(void) | ||
| 281 | { | ||
| 282 | return sysdev_class_register(&pxa_gpio_sysclass); | ||
| 283 | } | ||
| 284 | |||
| 285 | core_initcall(pxa_gpio_init); | ||
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 367b67923e11..1a16ad3ecee6 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h | |||
| @@ -54,3 +54,4 @@ extern unsigned pxa3xx_get_memclk_frequency_10khz(void); | |||
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | extern struct sysdev_class pxa_irq_sysclass; | 56 | extern struct sysdev_class pxa_irq_sysclass; |
| 57 | extern struct sysdev_class pxa_gpio_sysclass; | ||
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 797635eec6b6..599e53fcc2c5 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
| @@ -142,11 +142,6 @@ static struct clk pxa25x_clks[] = { | |||
| 142 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 142 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
| 143 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 143 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
| 144 | 144 | ||
| 145 | #define RESTORE_GPLEVEL(n) do { \ | ||
| 146 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
| 147 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
| 148 | } while (0) | ||
| 149 | |||
| 150 | /* | 145 | /* |
| 151 | * List of global PXA peripheral registers to preserve. | 146 | * List of global PXA peripheral registers to preserve. |
| 152 | * More ones like CP and general purpose register values are preserved | 147 | * More ones like CP and general purpose register values are preserved |
| @@ -154,10 +149,6 @@ static struct clk pxa25x_clks[] = { | |||
| 154 | */ | 149 | */ |
| 155 | enum { SLEEP_SAVE_START = 0, | 150 | enum { SLEEP_SAVE_START = 0, |
| 156 | 151 | ||
| 157 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, | ||
| 158 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, | ||
| 159 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, | ||
| 160 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, | ||
| 161 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, | 152 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, |
| 162 | 153 | ||
| 163 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | 154 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, |
| @@ -174,10 +165,6 @@ enum { SLEEP_SAVE_START = 0, | |||
| 174 | 165 | ||
| 175 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) | 166 | static void pxa25x_cpu_pm_save(unsigned long *sleep_save) |
| 176 | { | 167 | { |
| 177 | SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); | ||
| 178 | SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); | ||
| 179 | SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); | ||
| 180 | SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); | ||
| 181 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); | 168 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); |
| 182 | 169 | ||
| 183 | SAVE(GAFR0_L); SAVE(GAFR0_U); | 170 | SAVE(GAFR0_L); SAVE(GAFR0_U); |
| @@ -197,13 +184,9 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) | |||
| 197 | PSPR = 0; | 184 | PSPR = 0; |
| 198 | 185 | ||
| 199 | /* restore registers */ | 186 | /* restore registers */ |
| 200 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); | ||
| 201 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); | ||
| 202 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | 187 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); |
| 203 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | 188 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); |
| 204 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | 189 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); |
| 205 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); | ||
| 206 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); | ||
| 207 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | 190 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); |
| 208 | 191 | ||
| 209 | PSSR = PSSR_RDH | PSSR_PH; | 192 | PSSR = PSSR_RDH | PSSR_PH; |
| @@ -302,6 +285,8 @@ static struct platform_device *pxa25x_devices[] __initdata = { | |||
| 302 | static struct sys_device pxa25x_sysdev[] = { | 285 | static struct sys_device pxa25x_sysdev[] = { |
| 303 | { | 286 | { |
| 304 | .cls = &pxa_irq_sysclass, | 287 | .cls = &pxa_irq_sysclass, |
| 288 | }, { | ||
| 289 | .cls = &pxa_gpio_sysclass, | ||
| 305 | }, | 290 | }, |
| 306 | }; | 291 | }; |
| 307 | 292 | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 343296a710b3..46a951c3e5a0 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
| @@ -172,11 +172,6 @@ static struct clk pxa27x_clks[] = { | |||
| 172 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 172 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
| 173 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 173 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
| 174 | 174 | ||
| 175 | #define RESTORE_GPLEVEL(n) do { \ | ||
| 176 | GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
| 177 | GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ | ||
| 178 | } while (0) | ||
| 179 | |||
| 180 | /* | 175 | /* |
| 181 | * List of global PXA peripheral registers to preserve. | 176 | * List of global PXA peripheral registers to preserve. |
| 182 | * More ones like CP and general purpose register values are preserved | 177 | * More ones like CP and general purpose register values are preserved |
| @@ -184,10 +179,6 @@ static struct clk pxa27x_clks[] = { | |||
| 184 | */ | 179 | */ |
| 185 | enum { SLEEP_SAVE_START = 0, | 180 | enum { SLEEP_SAVE_START = 0, |
| 186 | 181 | ||
| 187 | SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, | ||
| 188 | SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, | ||
| 189 | SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, | ||
| 190 | SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, | ||
| 191 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, | 182 | SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, |
| 192 | 183 | ||
| 193 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, | 184 | SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, |
| @@ -208,10 +199,6 @@ enum { SLEEP_SAVE_START = 0, | |||
| 208 | 199 | ||
| 209 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) | 200 | void pxa27x_cpu_pm_save(unsigned long *sleep_save) |
| 210 | { | 201 | { |
| 211 | SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3); | ||
| 212 | SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3); | ||
| 213 | SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3); | ||
| 214 | SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3); | ||
| 215 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); | 202 | SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); |
| 216 | 203 | ||
| 217 | SAVE(GAFR0_L); SAVE(GAFR0_U); | 204 | SAVE(GAFR0_L); SAVE(GAFR0_U); |
| @@ -225,9 +212,6 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save) | |||
| 225 | 212 | ||
| 226 | SAVE(CKEN); | 213 | SAVE(CKEN); |
| 227 | SAVE(PSTR); | 214 | SAVE(PSTR); |
| 228 | |||
| 229 | /* Clear GPIO transition detect bits */ | ||
| 230 | GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3; | ||
| 231 | } | 215 | } |
| 232 | 216 | ||
| 233 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | 217 | void pxa27x_cpu_pm_restore(unsigned long *sleep_save) |
| @@ -236,15 +220,10 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | |||
| 236 | PSPR = 0; | 220 | PSPR = 0; |
| 237 | 221 | ||
| 238 | /* restore registers */ | 222 | /* restore registers */ |
| 239 | RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); | ||
| 240 | RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3); | ||
| 241 | RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3); | ||
| 242 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); | 223 | RESTORE(GAFR0_L); RESTORE(GAFR0_U); |
| 243 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); | 224 | RESTORE(GAFR1_L); RESTORE(GAFR1_U); |
| 244 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); | 225 | RESTORE(GAFR2_L); RESTORE(GAFR2_U); |
| 245 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); | 226 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); |
| 246 | RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3); | ||
| 247 | RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3); | ||
| 248 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); | 227 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); |
| 249 | 228 | ||
| 250 | RESTORE(MDREFR); | 229 | RESTORE(MDREFR); |
| @@ -412,6 +391,8 @@ static struct sys_device pxa27x_sysdev[] = { | |||
| 412 | }, { | 391 | }, { |
| 413 | .id = 1, | 392 | .id = 1, |
| 414 | .cls = &pxa_irq_sysclass, | 393 | .cls = &pxa_irq_sysclass, |
| 394 | }, { | ||
| 395 | .cls = &pxa_gpio_sysclass, | ||
| 415 | }, | 396 | }, |
| 416 | }; | 397 | }; |
| 417 | 398 | ||
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 3a7e8ccd70bd..d0b2afd4368a 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c | |||
| @@ -460,6 +460,8 @@ static struct sys_device pxa3xx_sysdev[] = { | |||
| 460 | }, { | 460 | }, { |
| 461 | .id = 1, | 461 | .id = 1, |
| 462 | .cls = &pxa_irq_sysclass, | 462 | .cls = &pxa_irq_sysclass, |
| 463 | }, { | ||
| 464 | .cls = &pxa_gpio_sysclass, | ||
| 463 | }, | 465 | }, |
| 464 | }; | 466 | }; |
| 465 | 467 | ||
