aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-pxa/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa/pm.c')
-rw-r--r--arch/arm/mach-pxa/pm.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index b59a81a8e7d..37178a8559b 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -14,15 +14,9 @@
#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/errno.h>
-#include <linux/time.h>
+#include <linux/slab.h>
-#include <asm/hardware.h>
-#include <asm/memory.h>
-#include <asm/system.h>
-#include <asm/arch/pm.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/lubbock.h>
-#include <asm/mach/time.h>
+#include <mach/pm.h>
struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
static unsigned long *sleep_save;
@@ -38,33 +32,32 @@ int pxa_pm_enter(suspend_state_t state)
iwmmxt_task_disable(NULL);
#endif
- pxa_cpu_pm_fns->save(sleep_save);
-
- /* Clear sleep reset status */
- RCSR = RCSR_SMR;
-
- /* before sleeping, calculate and save a checksum */
- for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
- sleep_save_checksum += sleep_save[i];
+ /* skip registers saving for standby */
+ if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) {
+ pxa_cpu_pm_fns->save(sleep_save);
+ /* before sleeping, calculate and save a checksum */
+ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
+ sleep_save_checksum += sleep_save[i];
+ }
/* *** go zzz *** */
pxa_cpu_pm_fns->enter(state);
- cpu_init();
- /* after sleeping, validate the checksum */
- for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
- checksum += sleep_save[i];
+ if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) {
+ /* after sleeping, validate the checksum */
+ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
+ checksum += sleep_save[i];
- /* if invalid, display message and wait for a hardware reset */
- if (checksum != sleep_save_checksum) {
-#ifdef CONFIG_ARCH_LUBBOCK
- LUB_HEXLED = 0xbadbadc5;
-#endif
- while (1)
- pxa_cpu_pm_fns->enter(state);
- }
+ /* if invalid, display message and wait for a hardware reset */
+ if (checksum != sleep_save_checksum) {
- pxa_cpu_pm_fns->restore(sleep_save);
+ lubbock_set_hexled(0xbadbadc5);
+
+ while (1)
+ pxa_cpu_pm_fns->enter(state);
+ }
+ pxa_cpu_pm_fns->restore(sleep_save);
+ }
pr_debug("*** made it back from resume\n");
@@ -73,11 +66,6 @@ int pxa_pm_enter(suspend_state_t state)
EXPORT_SYMBOL_GPL(pxa_pm_enter);
-unsigned long sleep_phys_sp(void *sp)
-{
- return virt_to_phys(sp);
-}
-
static int pxa_pm_valid(suspend_state_t state)
{
if (pxa_cpu_pm_fns)
@@ -86,9 +74,27 @@ static int pxa_pm_valid(suspend_state_t state)
return -EINVAL;
}
-static struct pm_ops pxa_pm_ops = {
+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;
+}
+
+void pxa_pm_finish(void)
+{
+ if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish)
+ pxa_cpu_pm_fns->finish();
+}
+
+static const 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)
@@ -98,13 +104,14 @@ static int __init pxa_pm_init(void)
return -EINVAL;
}
- sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
+ sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
+ GFP_KERNEL);
if (!sleep_save) {
printk(KERN_ERR "failed to alloc memory for pm save\n");
return -ENOMEM;
}
- pm_set_ops(&pxa_pm_ops);
+ suspend_set_ops(&pxa_pm_ops);
return 0;
}