summaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c51
1 files changed, 36 insertions, 15 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index aa9e916da4d5..657272e91d0a 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
- * Copyright (c) 2004 Pavel Machek <pavel@suse.cz>
+ * Copyright (c) 2004 Pavel Machek <pavel@ucw.cz>
* Copyright (c) 2009 Rafael J. Wysocki, Novell Inc.
*
* This file is released under the GPLv2.
@@ -29,6 +29,7 @@
#include "power.h"
+static int nocompress = 0;
static int noresume = 0;
static char resume_file[256] = CONFIG_PM_STD_PARTITION;
dev_t swsusp_resume_device;
@@ -277,7 +278,7 @@ static int create_image(int platform_mode)
goto Enable_irqs;
}
- if (hibernation_test(TEST_CORE))
+ if (hibernation_test(TEST_CORE) || !pm_check_wakeup_events())
goto Power_up;
in_suspend = 1;
@@ -288,8 +289,10 @@ static int create_image(int platform_mode)
error);
/* Restore control flow magically appears here */
restore_processor_state();
- if (!in_suspend)
+ if (!in_suspend) {
+ events_check_enabled = false;
platform_leave(platform_mode);
+ }
Power_up:
sysdev_resume();
@@ -328,7 +331,7 @@ int hibernation_snapshot(int platform_mode)
error = platform_begin(platform_mode);
if (error)
- return error;
+ goto Close;
/* Preallocate image memory before shutting down devices. */
error = hibernate_preallocate_memory();
@@ -511,18 +514,24 @@ int hibernation_platform_enter(void)
local_irq_disable();
sysdev_suspend(PMSG_HIBERNATE);
+ if (!pm_check_wakeup_events()) {
+ error = -EAGAIN;
+ goto Power_up;
+ }
+
hibernation_ops->enter();
/* We should never get here */
while (1);
- /*
- * We don't need to reenable the nonboot CPUs or resume consoles, since
- * the system is going to be halted anyway.
- */
+ Power_up:
+ sysdev_resume();
+ local_irq_enable();
+ enable_nonboot_cpus();
+
Platform_finish:
hibernation_ops->finish();
- dpm_suspend_noirq(PMSG_RESTORE);
+ dpm_resume_noirq(PMSG_RESTORE);
Resume_devices:
entering_platform_hibernation = false;
@@ -630,6 +639,8 @@ int hibernate(void)
if (hibernation_mode == HIBERNATION_PLATFORM)
flags |= SF_PLATFORM_MODE;
+ if (nocompress)
+ flags |= SF_NOCOMPRESS_MODE;
pr_debug("PM: writing image.\n");
error = swsusp_write(flags);
swsusp_free();
@@ -697,7 +708,7 @@ static int software_resume(void)
goto Unlock;
}
- pr_debug("PM: Checking image partition %s\n", resume_file);
+ pr_debug("PM: Checking hibernation image partition %s\n", resume_file);
/* Check if the device is there */
swsusp_resume_device = name_to_dev_t(resume_file);
@@ -722,10 +733,10 @@ static int software_resume(void)
}
Check_image:
- pr_debug("PM: Resume from partition %d:%d\n",
+ pr_debug("PM: Hibernation image partition %d:%d present\n",
MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
- pr_debug("PM: Checking hibernation image.\n");
+ pr_debug("PM: Looking for hibernation image.\n");
error = swsusp_check();
if (error)
goto Unlock;
@@ -757,14 +768,14 @@ static int software_resume(void)
goto Done;
}
- pr_debug("PM: Reading hibernation image.\n");
+ pr_debug("PM: Loading hibernation image.\n");
error = swsusp_read(&flags);
swsusp_close(FMODE_READ);
if (!error)
hibernation_restore(flags & SF_PLATFORM_MODE);
- printk(KERN_ERR "PM: Restore failed, recovering.\n");
+ printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n");
swsusp_free();
thaw_processes();
Done:
@@ -777,7 +788,7 @@ static int software_resume(void)
/* For success case, the suspend path will release the lock */
Unlock:
mutex_unlock(&pm_mutex);
- pr_debug("PM: Resume from disk failed.\n");
+ pr_debug("PM: Hibernation image not present or could not be loaded.\n");
return error;
close_finish:
swsusp_close(FMODE_READ);
@@ -996,6 +1007,15 @@ static int __init resume_offset_setup(char *str)
return 1;
}
+static int __init hibernate_setup(char *str)
+{
+ if (!strncmp(str, "noresume", 8))
+ noresume = 1;
+ else if (!strncmp(str, "nocompress", 10))
+ nocompress = 1;
+ return 1;
+}
+
static int __init noresume_setup(char *str)
{
noresume = 1;
@@ -1005,3 +1025,4 @@ static int __init noresume_setup(char *str)
__setup("noresume", noresume_setup);
__setup("resume_offset=", resume_offset_setup);
__setup("resume=", resume_setup);
+__setup("hibernate=", hibernate_setup);