Commit 16dfdbf038706c12c56f327d14c6b901edc376a3

Authored by eric miao
Committed by Russell King
1 parent c016550490

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

Showing 5 changed files with 64 additions and 38 deletions Side-by-side Diff

arch/arm/mach-pxa/generic.c
... ... @@ -23,6 +23,7 @@
23 23 #include <linux/ioport.h>
24 24 #include <linux/pm.h>
25 25 #include <linux/string.h>
  26 +#include <linux/sysdev.h>
26 27  
27 28 #include <asm/hardware.h>
28 29 #include <asm/irq.h>
... ... @@ -226,4 +227,60 @@
226 227 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
227 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);
arch/arm/mach-pxa/generic.h
... ... @@ -54,4 +54,5 @@
54 54 #endif
55 55  
56 56 extern struct sysdev_class pxa_irq_sysclass;
  57 +extern struct sysdev_class pxa_gpio_sysclass;
arch/arm/mach-pxa/pxa25x.c
... ... @@ -142,11 +142,6 @@
142 142 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
143 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 146 * List of global PXA peripheral registers to preserve.
152 147 * More ones like CP and general purpose register values are preserved
... ... @@ -154,10 +149,6 @@
154 149 */
155 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 152 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
162 153  
163 154 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
... ... @@ -174,10 +165,6 @@
174 165  
175 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 168 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
182 169  
183 170 SAVE(GAFR0_L); SAVE(GAFR0_U);
184 171  
... ... @@ -197,13 +184,9 @@
197 184 PSPR = 0;
198 185  
199 186 /* restore registers */
200   - RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
201   - RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
202 187 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
203 188 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
204 189 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
205   - RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
206   - RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
207 190 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
208 191  
209 192 PSSR = PSSR_RDH | PSSR_PH;
... ... @@ -302,6 +285,8 @@
302 285 static struct sys_device pxa25x_sysdev[] = {
303 286 {
304 287 .cls = &pxa_irq_sysclass,
  288 + }, {
  289 + .cls = &pxa_gpio_sysclass,
305 290 },
306 291 };
307 292  
arch/arm/mach-pxa/pxa27x.c
... ... @@ -172,11 +172,6 @@
172 172 #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
173 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 176 * List of global PXA peripheral registers to preserve.
182 177 * More ones like CP and general purpose register values are preserved
... ... @@ -184,10 +179,6 @@
184 179 */
185 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 182 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
192 183  
193 184 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
... ... @@ -208,10 +199,6 @@
208 199  
209 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 202 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
216 203  
217 204 SAVE(GAFR0_L); SAVE(GAFR0_U);
... ... @@ -225,9 +212,6 @@
225 212  
226 213 SAVE(CKEN);
227 214 SAVE(PSTR);
228   -
229   - /* Clear GPIO transition detect bits */
230   - GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3;
231 215 }
232 216  
233 217 void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
234 218  
... ... @@ -236,15 +220,10 @@
236 220 PSPR = 0;
237 221  
238 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 223 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
243 224 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
244 225 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
245 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 227 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
249 228  
250 229 RESTORE(MDREFR);
... ... @@ -412,6 +391,8 @@
412 391 }, {
413 392 .id = 1,
414 393 .cls = &pxa_irq_sysclass,
  394 + }, {
  395 + .cls = &pxa_gpio_sysclass,
415 396 },
416 397 };
417 398  
arch/arm/mach-pxa/pxa3xx.c
... ... @@ -460,6 +460,8 @@
460 460 }, {
461 461 .id = 1,
462 462 .cls = &pxa_irq_sysclass,
  463 + }, {
  464 + .cls = &pxa_gpio_sysclass,
463 465 },
464 466 };
465 467