*/
#undef DEBUG
-extern void pxa_cpu_suspend(void);
-extern void pxa_cpu_resume(void);
-
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
SLEEP_SAVE_ICMR,
SLEEP_SAVE_CKEN,
+#ifdef CONFIG_PXA27x
+ SLEEP_SAVE_MDREFR,
+ SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
+ SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
+#endif
+
SLEEP_SAVE_CKSUM,
SLEEP_SAVE_SIZE
unsigned long checksum = 0;
struct timespec delta, rtc;
int i;
-
- if (state != PM_SUSPEND_MEM)
- return -EINVAL;
+ extern void pxa_cpu_pm_enter(suspend_state_t state);
#ifdef CONFIG_IWMMXT
/* force any iWMMXt context to ram **/
SAVE(GAFR2_L); SAVE(GAFR2_U);
#ifdef CONFIG_PXA27x
+ SAVE(MDREFR);
SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
SAVE(GAFR3_L); SAVE(GAFR3_U);
+ SAVE(PWER); SAVE(PCFR); SAVE(PRER);
+ SAVE(PFER); SAVE(PKWR);
#endif
SAVE(ICMR);
ICMR = 0;
SAVE(CKEN);
- CKEN = 0;
-
SAVE(PSTR);
/* Note: wake up source are set up in each machine specific files */
/* Clear sleep reset status */
RCSR = RCSR_SMR;
- /* set resume return address */
- PSPR = virt_to_phys(pxa_cpu_resume);
-
/* before sleeping, calculate and save a checksum */
for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
checksum += sleep_save[i];
sleep_save[SLEEP_SAVE_CKSUM] = checksum;
/* *** go zzz *** */
- pxa_cpu_suspend();
+ pxa_cpu_pm_enter(state);
/* after sleeping, validate the checksum */
checksum = 0;
LUB_HEXLED = 0xbadbadc5;
#endif
while (1)
- pxa_cpu_suspend();
+ pxa_cpu_pm_enter(state);
}
/* ensure not to come back here if it wasn't intended */
RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
#ifdef CONFIG_PXA27x
+ RESTORE(MDREFR);
RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
+ RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
+ RESTORE(PFER); RESTORE(PKWR);
#endif
PSSR = PSSR_RDH | PSSR_PH;
*/
static int pxa_pm_prepare(suspend_state_t state)
{
- return 0;
+ extern int pxa_cpu_pm_prepare(suspend_state_t state);
+
+ return pxa_cpu_pm_prepare(state);
}
/*
EXPORT_SYMBOL(get_memclk_frequency_10khz);
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+int pxa_cpu_pm_prepare(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+void pxa_cpu_pm_enter(suspend_state_t state)
+{
+ extern void pxa_cpu_standby(void);
+ extern void pxa_cpu_suspend(unsigned int);
+ extern void pxa_cpu_resume(void);
+
+ CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+
+ /* ensure voltage-change sequencer not initiated, which hangs */
+ PCFR &= ~PCFR_FVC;
+
+ /* Clear edge-detect status register. */
+ PEDR = 0xDF12FE1B;
+
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ /* set resume return address */
+ PSPR = virt_to_phys(pxa_cpu_resume);
+ pxa_cpu_suspend(3);
+ break;
+ }
+}
/*
* device registration specific to PXA27x.