[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>

authored by eric miao and committed by Russell King 16dfdbf0 c0165504

+64 -38
+57
arch/arm/mach-pxa/generic.c
··· 23 #include <linux/ioport.h> 24 #include <linux/pm.h> 25 #include <linux/string.h> 26 27 #include <asm/hardware.h> 28 #include <asm/irq.h> ··· 227 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 228 get_clk_frequency_khz(1); 229 }
··· 23 #include <linux/ioport.h> 24 #include <linux/pm.h> 25 #include <linux/string.h> 26 + #include <linux/sysdev.h> 27 28 #include <asm/hardware.h> 29 #include <asm/irq.h> ··· 226 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 227 get_clk_frequency_khz(1); 228 } 229 + 230 + #ifdef CONFIG_PM 231 + 232 + static unsigned long saved_gplr[4]; 233 + static unsigned long saved_gpdr[4]; 234 + static unsigned long saved_grer[4]; 235 + static unsigned long saved_gfer[4]; 236 + 237 + static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state) 238 + { 239 + int i, gpio; 240 + 241 + for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { 242 + saved_gplr[i] = GPLR(gpio); 243 + saved_gpdr[i] = GPDR(gpio); 244 + saved_grer[i] = GRER(gpio); 245 + saved_gfer[i] = GFER(gpio); 246 + 247 + /* Clear GPIO transition detect bits */ 248 + GEDR(gpio) = GEDR(gpio); 249 + } 250 + return 0; 251 + } 252 + 253 + static int pxa_gpio_resume(struct sys_device *dev) 254 + { 255 + int i, gpio; 256 + 257 + for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) { 258 + /* restore level with set/clear */ 259 + GPSR(gpio) = saved_gplr[i]; 260 + GPCR(gpio) = ~saved_gplr[i]; 261 + 262 + GRER(gpio) = saved_grer[i]; 263 + GFER(gpio) = saved_gfer[i]; 264 + GPDR(gpio) = saved_gpdr[i]; 265 + } 266 + return 0; 267 + } 268 + #else 269 + #define pxa_gpio_suspend NULL 270 + #define pxa_gpio_resume NULL 271 + #endif 272 + 273 + struct sysdev_class pxa_gpio_sysclass = { 274 + .name = "gpio", 275 + .suspend = pxa_gpio_suspend, 276 + .resume = pxa_gpio_resume, 277 + }; 278 + 279 + static int __init pxa_gpio_init(void) 280 + { 281 + return sysdev_class_register(&pxa_gpio_sysclass); 282 + } 283 + 284 + core_initcall(pxa_gpio_init);
+1
arch/arm/mach-pxa/generic.h
··· 54 #endif 55 56 extern struct sysdev_class pxa_irq_sysclass;
··· 54 #endif 55 56 extern struct sysdev_class pxa_irq_sysclass; 57 + extern struct sysdev_class pxa_gpio_sysclass;
+2 -17
arch/arm/mach-pxa/pxa25x.c
··· 142 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 143 #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 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 /* 151 * List of global PXA peripheral registers to preserve. 152 * More ones like CP and general purpose register values are preserved ··· 149 */ 150 enum { SLEEP_SAVE_START = 0, 151 152 - SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, 153 - SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, 154 - SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, 155 - SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, 156 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, 157 158 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, ··· 165 166 static void pxa25x_cpu_pm_save(unsigned long *sleep_save) 167 { 168 - SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); 169 - SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); 170 - SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); 171 - SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); 172 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); 173 174 SAVE(GAFR0_L); SAVE(GAFR0_U); ··· 184 PSPR = 0; 185 186 /* restore registers */ 187 - RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); 188 - RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); 189 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 190 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 191 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 192 - RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); 193 - RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); 194 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 195 196 PSSR = PSSR_RDH | PSSR_PH; ··· 285 static struct sys_device pxa25x_sysdev[] = { 286 { 287 .cls = &pxa_irq_sysclass, 288 }, 289 }; 290
··· 142 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 143 #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 144 145 /* 146 * List of global PXA peripheral registers to preserve. 147 * More ones like CP and general purpose register values are preserved ··· 154 */ 155 enum { SLEEP_SAVE_START = 0, 156 157 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, 158 159 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, ··· 174 175 static void pxa25x_cpu_pm_save(unsigned long *sleep_save) 176 { 177 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); 178 179 SAVE(GAFR0_L); SAVE(GAFR0_U); ··· 197 PSPR = 0; 198 199 /* restore registers */ 200 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 201 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 202 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 203 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 204 205 PSSR = PSSR_RDH | PSSR_PH; ··· 302 static struct sys_device pxa25x_sysdev[] = { 303 { 304 .cls = &pxa_irq_sysclass, 305 + }, { 306 + .cls = &pxa_gpio_sysclass, 307 }, 308 }; 309
+2 -21
arch/arm/mach-pxa/pxa27x.c
··· 172 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 173 #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 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 /* 181 * List of global PXA peripheral registers to preserve. 182 * More ones like CP and general purpose register values are preserved ··· 179 */ 180 enum { SLEEP_SAVE_START = 0, 181 182 - SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, 183 - SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, 184 - SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, 185 - SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, 186 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, 187 188 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, ··· 199 200 void pxa27x_cpu_pm_save(unsigned long *sleep_save) 201 { 202 - SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3); 203 - SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3); 204 - SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3); 205 - SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3); 206 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); 207 208 SAVE(GAFR0_L); SAVE(GAFR0_U); ··· 212 213 SAVE(CKEN); 214 SAVE(PSTR); 215 - 216 - /* Clear GPIO transition detect bits */ 217 - GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3; 218 } 219 220 void pxa27x_cpu_pm_restore(unsigned long *sleep_save) ··· 220 PSPR = 0; 221 222 /* restore registers */ 223 - RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); 224 - RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3); 225 - RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3); 226 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 227 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 228 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 229 RESTORE(GAFR3_L); RESTORE(GAFR3_U); 230 - RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3); 231 - RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3); 232 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); 233 234 RESTORE(MDREFR); ··· 391 }, { 392 .id = 1, 393 .cls = &pxa_irq_sysclass, 394 }, 395 }; 396
··· 172 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 173 #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 174 175 /* 176 * List of global PXA peripheral registers to preserve. 177 * More ones like CP and general purpose register values are preserved ··· 184 */ 185 enum { SLEEP_SAVE_START = 0, 186 187 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, 188 189 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, ··· 208 209 void pxa27x_cpu_pm_save(unsigned long *sleep_save) 210 { 211 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); 212 213 SAVE(GAFR0_L); SAVE(GAFR0_U); ··· 225 226 SAVE(CKEN); 227 SAVE(PSTR); 228 } 229 230 void pxa27x_cpu_pm_restore(unsigned long *sleep_save) ··· 236 PSPR = 0; 237 238 /* restore registers */ 239 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 240 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 241 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 242 RESTORE(GAFR3_L); RESTORE(GAFR3_U); 243 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); 244 245 RESTORE(MDREFR); ··· 412 }, { 413 .id = 1, 414 .cls = &pxa_irq_sysclass, 415 + }, { 416 + .cls = &pxa_gpio_sysclass, 417 }, 418 }; 419
+2
arch/arm/mach-pxa/pxa3xx.c
··· 460 }, { 461 .id = 1, 462 .cls = &pxa_irq_sysclass, 463 }, 464 }; 465
··· 460 }, { 461 .id = 1, 462 .cls = &pxa_irq_sysclass, 463 + }, { 464 + .cls = &pxa_gpio_sysclass, 465 }, 466 }; 467