[ARM] 4488/1: pxa: move pxa25x/pxa27x specific code out of pm.c

1. introduce a structure pxa_cpu_pm_fns for pxa25x/pxa27x specific
operations as follows:

struct pxa_cpu_pm_fns {
int save_size;
void (*save)(unsigned long *);
void (*restore)(unsigned long *);
int (*valid)(suspend_state_t state);
void (*enter)(suspend_state_t state);
}

2. processor specific registers saving and restoring are performed
by calling the corresponding (*save) and (*restore)

3. pxa_cpu_pm_fns->save_size should be initialized to the required
size for processor specific registers saving, the allocated
memory address will be passed to (*save) and (*restore)

memory allocation happens early in pxa_pm_init(), and save_size
should be assigned prior to this (which is usually true, since
pxa_pm_init() happens in device_initcall()

4. there're some redundancies for those SLEEP_SAVE_XXX and related
macros, will be fixed later, one way possible is for the system
devices to handle the specific registers saving and restoring

Signed-off-by: eric miao <eric.y.miao@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Eric Miao and committed by Russell King 711be5cc e09d02e1

+244 -137
+44 -125
arch/arm/mach-pxa/pm.c
··· 24 #include <asm/arch/lubbock.h> 25 #include <asm/mach/time.h> 26 27 - 28 - /* 29 - * Debug macros 30 - */ 31 - #undef DEBUG 32 - 33 - #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 34 - #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 35 - 36 - #define RESTORE_GPLEVEL(n) do { \ 37 - GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ 38 - GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ 39 - } while (0) 40 - 41 - /* 42 - * List of global PXA peripheral registers to preserve. 43 - * More ones like CP and general purpose register values are preserved 44 - * with the stack pointer in sleep.S. 45 - */ 46 - enum { SLEEP_SAVE_START = 0, 47 - 48 - SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, 49 - SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, 50 - SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, 51 - SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, 52 - SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, 53 - 54 - SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 55 - SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, 56 - SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, 57 - SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, 58 - 59 - SLEEP_SAVE_PSTR, 60 - 61 - SLEEP_SAVE_ICMR, 62 - SLEEP_SAVE_CKEN, 63 - 64 - #ifdef CONFIG_PXA27x 65 - SLEEP_SAVE_MDREFR, 66 - SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, 67 - SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, 68 - #endif 69 - 70 - SLEEP_SAVE_CKSUM, 71 - 72 - SLEEP_SAVE_SIZE 73 - }; 74 - 75 76 int pxa_pm_enter(suspend_state_t state) 77 { 78 - unsigned long sleep_save[SLEEP_SAVE_SIZE]; 79 - unsigned long checksum = 0; 80 int i; 81 - extern void pxa_cpu_pm_enter(suspend_state_t state); 82 83 #ifdef CONFIG_IWMMXT 84 /* force any iWMMXt context to ram **/ ··· 38 iwmmxt_task_disable(NULL); 39 #endif 40 41 - SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); 42 - SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); 43 - SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); 44 - SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); 45 - SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); 46 - 47 - SAVE(GAFR0_L); SAVE(GAFR0_U); 48 - SAVE(GAFR1_L); SAVE(GAFR1_U); 49 - SAVE(GAFR2_L); SAVE(GAFR2_U); 50 - 51 - #ifdef CONFIG_PXA27x 52 - SAVE(MDREFR); 53 - SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); 54 - SAVE(GAFR3_L); SAVE(GAFR3_U); 55 - SAVE(PWER); SAVE(PCFR); SAVE(PRER); 56 - SAVE(PFER); SAVE(PKWR); 57 - #endif 58 - 59 - SAVE(ICMR); 60 - ICMR = 0; 61 - 62 - SAVE(CKEN); 63 - SAVE(PSTR); 64 - 65 - /* Note: wake up source are set up in each machine specific files */ 66 - 67 - /* clear GPIO transition detect bits */ 68 - GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; 69 - #ifdef CONFIG_PXA27x 70 - GEDR3 = GEDR3; 71 - #endif 72 73 /* Clear sleep reset status */ 74 RCSR = RCSR_SMR; 75 76 /* before sleeping, calculate and save a checksum */ 77 - for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) 78 - checksum += sleep_save[i]; 79 - sleep_save[SLEEP_SAVE_CKSUM] = checksum; 80 81 /* *** go zzz *** */ 82 - pxa_cpu_pm_enter(state); 83 - 84 cpu_init(); 85 86 /* after sleeping, validate the checksum */ 87 - checksum = 0; 88 - for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) 89 checksum += sleep_save[i]; 90 91 /* if invalid, display message and wait for a hardware reset */ 92 - if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) { 93 #ifdef CONFIG_ARCH_LUBBOCK 94 LUB_HEXLED = 0xbadbadc5; 95 #endif 96 while (1) 97 - pxa_cpu_pm_enter(state); 98 } 99 100 - /* ensure not to come back here if it wasn't intended */ 101 - PSPR = 0; 102 103 - /* restore registers */ 104 - RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); 105 - RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); 106 - RESTORE(GAFR0_L); RESTORE(GAFR0_U); 107 - RESTORE(GAFR1_L); RESTORE(GAFR1_U); 108 - RESTORE(GAFR2_L); RESTORE(GAFR2_U); 109 - RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); 110 - RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); 111 - RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 112 - 113 - #ifdef CONFIG_PXA27x 114 - RESTORE(MDREFR); 115 - RESTORE_GPLEVEL(3); RESTORE(GPDR3); 116 - RESTORE(GAFR3_L); RESTORE(GAFR3_U); 117 - RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); 118 - RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); 119 - RESTORE(PFER); RESTORE(PKWR); 120 - #endif 121 - 122 - PSSR = PSSR_RDH | PSSR_PH; 123 - 124 - RESTORE(CKEN); 125 - 126 - ICLR = 0; 127 - ICCR = 1; 128 - RESTORE(ICMR); 129 - 130 - RESTORE(PSTR); 131 - 132 - #ifdef DEBUG 133 - printk(KERN_DEBUG "*** made it back from resume\n"); 134 - #endif 135 136 return 0; 137 } ··· 77 { 78 return virt_to_phys(sp); 79 }
··· 24 #include <asm/arch/lubbock.h> 25 #include <asm/mach/time.h> 26 27 + struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; 28 + static unsigned long *sleep_save; 29 30 int pxa_pm_enter(suspend_state_t state) 31 { 32 + unsigned long sleep_save_checksum = 0, checksum = 0; 33 int i; 34 35 #ifdef CONFIG_IWMMXT 36 /* force any iWMMXt context to ram **/ ··· 86 iwmmxt_task_disable(NULL); 87 #endif 88 89 + pxa_cpu_pm_fns->save(sleep_save); 90 91 /* Clear sleep reset status */ 92 RCSR = RCSR_SMR; 93 94 /* before sleeping, calculate and save a checksum */ 95 + for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) 96 + sleep_save_checksum += sleep_save[i]; 97 98 /* *** go zzz *** */ 99 + pxa_cpu_pm_fns->enter(state); 100 cpu_init(); 101 102 /* after sleeping, validate the checksum */ 103 + for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++) 104 checksum += sleep_save[i]; 105 106 /* if invalid, display message and wait for a hardware reset */ 107 + if (checksum != sleep_save_checksum) { 108 #ifdef CONFIG_ARCH_LUBBOCK 109 LUB_HEXLED = 0xbadbadc5; 110 #endif 111 while (1) 112 + pxa_cpu_pm_fns->enter(state); 113 } 114 115 + pxa_cpu_pm_fns->restore(sleep_save); 116 117 + pr_debug("*** made it back from resume\n"); 118 119 return 0; 120 } ··· 190 { 191 return virt_to_phys(sp); 192 } 193 + 194 + static int pxa_pm_valid(suspend_state_t state) 195 + { 196 + if (pxa_cpu_pm_fns) 197 + return pxa_cpu_pm_fns->valid(state); 198 + 199 + return -EINVAL; 200 + } 201 + 202 + static struct pm_ops pxa_pm_ops = { 203 + .valid = pxa_pm_valid, 204 + .enter = pxa_pm_enter, 205 + }; 206 + 207 + static int __init pxa_pm_init(void) 208 + { 209 + if (!pxa_cpu_pm_fns) { 210 + printk(KERN_ERR "no valid pxa_cpu_pm_fns defined\n"); 211 + return -EINVAL; 212 + } 213 + 214 + sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL); 215 + if (!sleep_save) { 216 + printk(KERN_ERR "failed to alloc memory for pm save\n"); 217 + return -ENOMEM; 218 + } 219 + 220 + pm_set_ops(&pxa_pm_ops); 221 + return 0; 222 + } 223 + 224 + device_initcall(pxa_pm_init);
+80 -4
arch/arm/mach-pxa/pxa25x.c
··· 110 111 #ifdef CONFIG_PM 112 113 - void pxa_cpu_pm_enter(suspend_state_t state) 114 { 115 extern void pxa_cpu_suspend(unsigned int); 116 extern void pxa_cpu_resume(void); ··· 194 } 195 } 196 197 - static struct pm_ops pxa25x_pm_ops = { 198 - .enter = pxa_pm_enter, 199 .valid = pm_valid_only_mem, 200 }; 201 #endif 202 203 void __init pxa25x_init_irq(void) ··· 235 if ((ret = pxa_init_dma(16))) 236 return ret; 237 #ifdef CONFIG_PM 238 - pm_set_ops(&pxa25x_pm_ops); 239 #endif 240 ret = platform_add_devices(pxa25x_devices, 241 ARRAY_SIZE(pxa25x_devices));
··· 110 111 #ifdef CONFIG_PM 112 113 + #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 114 + #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 115 + 116 + #define RESTORE_GPLEVEL(n) do { \ 117 + GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ 118 + GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ 119 + } while (0) 120 + 121 + /* 122 + * List of global PXA peripheral registers to preserve. 123 + * More ones like CP and general purpose register values are preserved 124 + * with the stack pointer in sleep.S. 125 + */ 126 + enum { SLEEP_SAVE_START = 0, 127 + 128 + SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, 129 + SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, 130 + SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, 131 + SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, 132 + SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, 133 + 134 + SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 135 + SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, 136 + SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, 137 + 138 + SLEEP_SAVE_PSTR, 139 + 140 + SLEEP_SAVE_ICMR, 141 + SLEEP_SAVE_CKEN, 142 + 143 + SLEEP_SAVE_SIZE 144 + }; 145 + 146 + 147 + static void pxa25x_cpu_pm_save(unsigned long *sleep_save) 148 + { 149 + SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); 150 + SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); 151 + SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); 152 + SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); 153 + SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); 154 + 155 + SAVE(GAFR0_L); SAVE(GAFR0_U); 156 + SAVE(GAFR1_L); SAVE(GAFR1_U); 157 + SAVE(GAFR2_L); SAVE(GAFR2_U); 158 + 159 + SAVE(ICMR); 160 + SAVE(CKEN); 161 + SAVE(PSTR); 162 + } 163 + 164 + static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) 165 + { 166 + /* restore registers */ 167 + RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); 168 + RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); 169 + RESTORE(GAFR0_L); RESTORE(GAFR0_U); 170 + RESTORE(GAFR1_L); RESTORE(GAFR1_U); 171 + RESTORE(GAFR2_L); RESTORE(GAFR2_U); 172 + RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); 173 + RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); 174 + RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 175 + 176 + RESTORE(CKEN); 177 + RESTORE(ICMR); 178 + RESTORE(PSTR); 179 + } 180 + 181 + static void pxa25x_cpu_pm_enter(suspend_state_t state) 182 { 183 extern void pxa_cpu_suspend(unsigned int); 184 extern void pxa_cpu_resume(void); ··· 126 } 127 } 128 129 + static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { 130 + .save_size = SLEEP_SAVE_SIZE, 131 .valid = pm_valid_only_mem, 132 + .save = pxa25x_cpu_pm_save, 133 + .restore = pxa25x_cpu_pm_restore, 134 + .enter = pxa25x_cpu_pm_enter, 135 }; 136 + 137 + static void __init pxa25x_init_pm(void) 138 + { 139 + pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; 140 + } 141 #endif 142 143 void __init pxa25x_init_irq(void) ··· 159 if ((ret = pxa_init_dma(16))) 160 return ret; 161 #ifdef CONFIG_PM 162 + pxa25x_init_pm(); 163 #endif 164 ret = platform_add_devices(pxa25x_devices, 165 ARRAY_SIZE(pxa25x_devices));
+110 -7
arch/arm/mach-pxa/pxa27x.c
··· 126 127 #ifdef CONFIG_PM 128 129 - void pxa_cpu_pm_enter(suspend_state_t state) 130 { 131 extern void pxa_cpu_standby(void); 132 extern void pxa_cpu_suspend(unsigned int); 133 extern void pxa_cpu_resume(void); 134 135 if (state == PM_SUSPEND_STANDBY) 136 - CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | (1 << CKEN_LCD) | (1 << CKEN_PWM0); 137 else 138 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); 139 ··· 250 } 251 } 252 253 - static int pxa27x_pm_valid(suspend_state_t state) 254 { 255 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; 256 } 257 258 - static struct pm_ops pxa27x_pm_ops = { 259 - .enter = pxa_pm_enter, 260 - .valid = pxa27x_pm_valid, 261 }; 262 #endif 263 264 /* ··· 352 if ((ret = pxa_init_dma(32))) 353 return ret; 354 #ifdef CONFIG_PM 355 - pm_set_ops(&pxa27x_pm_ops); 356 #endif 357 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 358 }
··· 126 127 #ifdef CONFIG_PM 128 129 + #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 130 + #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 131 + 132 + #define RESTORE_GPLEVEL(n) do { \ 133 + GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ 134 + GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ 135 + } while (0) 136 + 137 + /* 138 + * List of global PXA peripheral registers to preserve. 139 + * More ones like CP and general purpose register values are preserved 140 + * with the stack pointer in sleep.S. 141 + */ 142 + enum { SLEEP_SAVE_START = 0, 143 + 144 + SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3, 145 + SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3, 146 + SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3, 147 + SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3, 148 + SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, 149 + 150 + SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 151 + SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, 152 + SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, 153 + SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U, 154 + 155 + SLEEP_SAVE_PSTR, 156 + 157 + SLEEP_SAVE_ICMR, 158 + SLEEP_SAVE_CKEN, 159 + 160 + SLEEP_SAVE_MDREFR, 161 + SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, 162 + SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, 163 + 164 + SLEEP_SAVE_SIZE 165 + }; 166 + 167 + void pxa27x_cpu_pm_save(unsigned long *sleep_save) 168 + { 169 + SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3); 170 + SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3); 171 + SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3); 172 + SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3); 173 + SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); 174 + 175 + SAVE(GAFR0_L); SAVE(GAFR0_U); 176 + SAVE(GAFR1_L); SAVE(GAFR1_U); 177 + SAVE(GAFR2_L); SAVE(GAFR2_U); 178 + SAVE(GAFR3_L); SAVE(GAFR3_U); 179 + 180 + SAVE(MDREFR); 181 + SAVE(PWER); SAVE(PCFR); SAVE(PRER); 182 + SAVE(PFER); SAVE(PKWR); 183 + 184 + SAVE(ICMR); ICMR = 0; 185 + SAVE(CKEN); 186 + SAVE(PSTR); 187 + 188 + /* Clear GPIO transition detect bits */ 189 + GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3; 190 + } 191 + 192 + void pxa27x_cpu_pm_restore(unsigned long *sleep_save) 193 + { 194 + /* ensure not to come back here if it wasn't intended */ 195 + PSPR = 0; 196 + 197 + /* restore registers */ 198 + RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); 199 + RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3); 200 + RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3); 201 + RESTORE(GAFR0_L); RESTORE(GAFR0_U); 202 + RESTORE(GAFR1_L); RESTORE(GAFR1_U); 203 + RESTORE(GAFR2_L); RESTORE(GAFR2_U); 204 + RESTORE(GAFR3_L); RESTORE(GAFR3_U); 205 + RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3); 206 + RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3); 207 + RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); 208 + 209 + RESTORE(MDREFR); 210 + RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); 211 + RESTORE(PFER); RESTORE(PKWR); 212 + 213 + PSSR = PSSR_RDH | PSSR_PH; 214 + 215 + RESTORE(CKEN); 216 + 217 + ICLR = 0; 218 + ICCR = 1; 219 + RESTORE(ICMR); 220 + RESTORE(PSTR); 221 + } 222 + 223 + void pxa27x_cpu_pm_enter(suspend_state_t state) 224 { 225 extern void pxa_cpu_standby(void); 226 extern void pxa_cpu_suspend(unsigned int); 227 extern void pxa_cpu_resume(void); 228 229 if (state == PM_SUSPEND_STANDBY) 230 + CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | 231 + (1 << CKEN_LCD) | (1 << CKEN_PWM0); 232 else 233 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); 234 ··· 155 } 156 } 157 158 + static int pxa27x_cpu_pm_valid(suspend_state_t state) 159 { 160 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; 161 } 162 163 + static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = { 164 + .save_size = SLEEP_SAVE_SIZE, 165 + .save = pxa27x_cpu_pm_save, 166 + .restore = pxa27x_cpu_pm_restore, 167 + .valid = pxa27x_cpu_pm_valid, 168 + .enter = pxa27x_cpu_pm_enter, 169 }; 170 + 171 + static void __init pxa27x_init_pm(void) 172 + { 173 + pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns; 174 + } 175 #endif 176 177 /* ··· 249 if ((ret = pxa_init_dma(32))) 250 return ret; 251 #ifdef CONFIG_PM 252 + pxa27x_init_pm(); 253 #endif 254 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 255 }
+10 -1
include/asm-arm/arch-pxa/pm.h
··· 7 * 8 */ 9 10 - extern int pxa_pm_prepare(suspend_state_t state); 11 extern int pxa_pm_enter(suspend_state_t state);
··· 7 * 8 */ 9 10 + struct pxa_cpu_pm_fns { 11 + int save_size; 12 + void (*save)(unsigned long *); 13 + void (*restore)(unsigned long *); 14 + int (*valid)(suspend_state_t state); 15 + void (*enter)(suspend_state_t state); 16 + }; 17 + 18 + extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; 19 + 20 extern int pxa_pm_enter(suspend_state_t state);