aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/pxa27x.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/pxa27x.c')
-rw-r--r--arch/arm/mach-pxa/pxa27x.c151
1 files changed, 126 insertions, 25 deletions
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index aa5bb02c897b..203371ab19db 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -126,14 +126,107 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
126 126
127#ifdef CONFIG_PM 127#ifdef CONFIG_PM
128 128
129void pxa_cpu_pm_enter(suspend_state_t state) 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 */
142enum { 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
167void 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
192void 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
223void pxa27x_cpu_pm_enter(suspend_state_t state)
130{ 224{
131 extern void pxa_cpu_standby(void); 225 extern void pxa_cpu_standby(void);
132 extern void pxa_cpu_suspend(unsigned int);
133 extern void pxa_cpu_resume(void);
134 226
135 if (state == PM_SUSPEND_STANDBY) 227 if (state == PM_SUSPEND_STANDBY)
136 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | (1 << CKEN_LCD) | (1 << CKEN_PWM0); 228 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) |
229 (1 << CKEN_LCD) | (1 << CKEN_PWM0);
137 else 230 else
138 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER); 231 CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER);
139 232
@@ -150,20 +243,28 @@ void pxa_cpu_pm_enter(suspend_state_t state)
150 case PM_SUSPEND_MEM: 243 case PM_SUSPEND_MEM:
151 /* set resume return address */ 244 /* set resume return address */
152 PSPR = virt_to_phys(pxa_cpu_resume); 245 PSPR = virt_to_phys(pxa_cpu_resume);
153 pxa_cpu_suspend(PWRMODE_SLEEP); 246 pxa27x_cpu_suspend(PWRMODE_SLEEP);
154 break; 247 break;
155 } 248 }
156} 249}
157 250
158static int pxa27x_pm_valid(suspend_state_t state) 251static int pxa27x_cpu_pm_valid(suspend_state_t state)
159{ 252{
160 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; 253 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
161} 254}
162 255
163static struct pm_ops pxa27x_pm_ops = { 256static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
164 .enter = pxa_pm_enter, 257 .save_size = SLEEP_SAVE_SIZE,
165 .valid = pxa27x_pm_valid, 258 .save = pxa27x_cpu_pm_save,
259 .restore = pxa27x_cpu_pm_restore,
260 .valid = pxa27x_cpu_pm_valid,
261 .enter = pxa27x_cpu_pm_enter,
166}; 262};
263
264static void __init pxa27x_init_pm(void)
265{
266 pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
267}
167#endif 268#endif
168 269
169/* 270/*
@@ -185,7 +286,7 @@ static struct resource pxa27x_ohci_resources[] = {
185 }, 286 },
186}; 287};
187 288
188static struct platform_device pxaohci_device = { 289static struct platform_device pxa27x_device_ohci = {
189 .name = "pxa27x-ohci", 290 .name = "pxa27x-ohci",
190 .id = -1, 291 .id = -1,
191 .dev = { 292 .dev = {
@@ -198,7 +299,7 @@ static struct platform_device pxaohci_device = {
198 299
199void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) 300void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
200{ 301{
201 pxaohci_device.dev.platform_data = info; 302 pxa27x_device_ohci.dev.platform_data = info;
202} 303}
203 304
204static struct resource i2c_power_resources[] = { 305static struct resource i2c_power_resources[] = {
@@ -213,7 +314,7 @@ static struct resource i2c_power_resources[] = {
213 }, 314 },
214}; 315};
215 316
216static struct platform_device pxai2c_power_device = { 317static struct platform_device pxa27x_device_i2c_power = {
217 .name = "pxa2xx-i2c", 318 .name = "pxa2xx-i2c",
218 .id = 1, 319 .id = 1,
219 .resource = i2c_power_resources, 320 .resource = i2c_power_resources,
@@ -221,18 +322,18 @@ static struct platform_device pxai2c_power_device = {
221}; 322};
222 323
223static struct platform_device *devices[] __initdata = { 324static struct platform_device *devices[] __initdata = {
224 &pxamci_device, 325 &pxa_device_mci,
225 &pxaudc_device, 326 &pxa_device_udc,
226 &pxafb_device, 327 &pxa_device_fb,
227 &ffuart_device, 328 &pxa_device_ffuart,
228 &btuart_device, 329 &pxa_device_btuart,
229 &stuart_device, 330 &pxa_device_stuart,
230 &pxai2c_device, 331 &pxa_device_i2c,
231 &pxai2c_power_device, 332 &pxa_device_i2s,
232 &pxai2s_device, 333 &pxa_device_ficp,
233 &pxaficp_device, 334 &pxa_device_rtc,
234 &pxartc_device, 335 &pxa27x_device_i2c_power,
235 &pxaohci_device, 336 &pxa27x_device_ohci,
236}; 337};
237 338
238void __init pxa27x_init_irq(void) 339void __init pxa27x_init_irq(void)
@@ -249,7 +350,7 @@ static int __init pxa27x_init(void)
249 if ((ret = pxa_init_dma(32))) 350 if ((ret = pxa_init_dma(32)))
250 return ret; 351 return ret;
251#ifdef CONFIG_PM 352#ifdef CONFIG_PM
252 pm_set_ops(&pxa27x_pm_ops); 353 pxa27x_init_pm();
253#endif 354#endif
254 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 355 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
255 } 356 }