void    (*restore)(unsigned long *);
        int     (*valid)(suspend_state_t state);
        void    (*enter)(suspend_state_t state);
+       int     (*prepare)(void);
+       void    (*finish)(void);
 };
 
 extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
 
        return -EINVAL;
 }
 
+static int pxa_pm_prepare(void)
+{
+       int ret = 0;
+
+       if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->prepare)
+               ret = pxa_cpu_pm_fns->prepare();
+
+       return ret;
+}
+
+static void pxa_pm_finish(void)
+{
+       if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish)
+               pxa_cpu_pm_fns->finish();
+}
+
 static struct platform_suspend_ops pxa_pm_ops = {
        .valid          = pxa_pm_valid,
        .enter          = pxa_pm_enter,
+       .prepare        = pxa_pm_prepare,
+       .finish         = pxa_pm_finish,
 };
 
 static int __init pxa_pm_init(void)
 
 
 static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
 {
-       /* ensure not to come back here if it wasn't intended */
-       PSPR = 0;
-
        /* restore registers */
        RESTORE(GAFR0_L); RESTORE(GAFR0_U);
        RESTORE(GAFR1_L); RESTORE(GAFR1_U);
 
        switch (state) {
        case PM_SUSPEND_MEM:
-               /* set resume return address */
-               PSPR = virt_to_phys(pxa_cpu_resume);
                pxa25x_cpu_suspend(PWRMODE_SLEEP);
                break;
        }
 }
 
+static int pxa25x_cpu_pm_prepare(void)
+{
+       /* set resume return address */
+       PSPR = virt_to_phys(pxa_cpu_resume);
+       return 0;
+}
+
+static void pxa25x_cpu_pm_finish(void)
+{
+       /* ensure not to come back here if it wasn't intended */
+       PSPR = 0;
+}
+
 static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
        .save_count     = SLEEP_SAVE_COUNT,
        .valid          = suspend_valid_only_mem,
        .save           = pxa25x_cpu_pm_save,
        .restore        = pxa25x_cpu_pm_restore,
        .enter          = pxa25x_cpu_pm_enter,
+       .prepare        = pxa25x_cpu_pm_prepare,
+       .finish         = pxa25x_cpu_pm_finish,
 };
 
 static void __init pxa25x_init_pm(void)
 
 
 void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
 {
-       /* ensure not to come back here if it wasn't intended */
-       PSPR = 0;
-
        /* restore registers */
        RESTORE(GAFR0_L); RESTORE(GAFR0_U);
        RESTORE(GAFR1_L); RESTORE(GAFR1_U);
                pxa_cpu_standby();
                break;
        case PM_SUSPEND_MEM:
-               /* set resume return address */
-               PSPR = virt_to_phys(pxa_cpu_resume);
                pxa27x_cpu_suspend(PWRMODE_SLEEP);
                break;
        }
        return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
 }
 
+static int pxa27x_cpu_pm_prepare(void)
+{
+       /* set resume return address */
+       PSPR = virt_to_phys(pxa_cpu_resume);
+       return 0;
+}
+
+static void pxa27x_cpu_pm_finish(void)
+{
+       /* ensure not to come back here if it wasn't intended */
+       PSPR = 0;
+}
+
 static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
        .save_count     = SLEEP_SAVE_COUNT,
        .save           = pxa27x_cpu_pm_save,
        .restore        = pxa27x_cpu_pm_restore,
        .valid          = pxa27x_cpu_pm_valid,
        .enter          = pxa27x_cpu_pm_enter,
+       .prepare        = pxa27x_cpu_pm_prepare,
+       .finish         = pxa27x_cpu_pm_finish,
 };
 
 static void __init pxa27x_init_pm(void)