Commit ed746e3b authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds

[PATCH] swsusp: Change code ordering in disk.c

Change the ordering of code in kernel/power/disk.c so that device_suspend() is
called before disable_nonboot_cpus() and platform_finish() is called after
enable_nonboot_cpus() and before device_resume(), as indicated by the recent
discussion on Linux-PM (cf.
http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html).

The changes here only affect the built-in swsusp.

[alexey.y.starikovskiy@linux.intel.com: fix LED blinking during image load]
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Acked-by: default avatarPavel Machek <pavel@ucw.cz>
Cc: Greg KH <greg@kroah.com>
Cc: Nigel Cunningham <nigel@suspend2.net>
Cc: Patrick Mochel <mochel@digitalimplant.org>
Cc: Alexey Starikovskiy <alexey.y.starikovskiy@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e3c7db62
...@@ -309,6 +309,8 @@ void enable_nonboot_cpus(void) ...@@ -309,6 +309,8 @@ void enable_nonboot_cpus(void)
mutex_lock(&cpu_add_remove_lock); mutex_lock(&cpu_add_remove_lock);
cpu_hotplug_disabled = 0; cpu_hotplug_disabled = 0;
mutex_unlock(&cpu_add_remove_lock); mutex_unlock(&cpu_add_remove_lock);
if (cpus_empty(frozen_cpus))
return;
printk("Enabling non-boot CPUs ...\n"); printk("Enabling non-boot CPUs ...\n");
for_each_cpu_mask(cpu, frozen_cpus) { for_each_cpu_mask(cpu, frozen_cpus) {
......
...@@ -87,52 +87,24 @@ static inline void platform_finish(void) ...@@ -87,52 +87,24 @@ static inline void platform_finish(void)
} }
} }
static void unprepare_processes(void)
{
thaw_processes();
pm_restore_console();
}
static int prepare_processes(void) static int prepare_processes(void)
{ {
int error = 0; int error = 0;
pm_prepare_console(); pm_prepare_console();
error = disable_nonboot_cpus();
if (error)
goto enable_cpus;
if (freeze_processes()) { if (freeze_processes()) {
error = -EBUSY; error = -EBUSY;
goto thaw; unprepare_processes();
} }
if (pm_disk_mode == PM_DISK_TESTPROC) {
printk("swsusp debug: Waiting for 5 seconds.\n");
mdelay(5000);
goto thaw;
}
error = platform_prepare();
if (error)
goto thaw;
/* Free memory before shutting down devices. */
if (!(error = swsusp_shrink_memory()))
return 0;
platform_finish();
thaw:
thaw_processes();
enable_cpus:
enable_nonboot_cpus();
pm_restore_console();
return error; return error;
} }
static void unprepare_processes(void)
{
platform_finish();
thaw_processes();
enable_nonboot_cpus();
pm_restore_console();
}
/** /**
* pm_suspend_disk - The granpappy of hibernation power management. * pm_suspend_disk - The granpappy of hibernation power management.
* *
...@@ -150,29 +122,45 @@ int pm_suspend_disk(void) ...@@ -150,29 +122,45 @@ int pm_suspend_disk(void)
if (error) if (error)
return error; return error;
if (pm_disk_mode == PM_DISK_TESTPROC) if (pm_disk_mode == PM_DISK_TESTPROC) {
return 0; printk("swsusp debug: Waiting for 5 seconds.\n");
mdelay(5000);
goto Thaw;
}
/* Free memory before shutting down devices. */
error = swsusp_shrink_memory();
if (error)
goto Thaw;
error = platform_prepare();
if (error)
goto Thaw;
suspend_console(); suspend_console();
error = device_suspend(PMSG_FREEZE); error = device_suspend(PMSG_FREEZE);
if (error) { if (error) {
resume_console(); printk(KERN_ERR "PM: Some devices failed to suspend\n");
printk("Some devices failed to suspend\n"); goto Resume_devices;
goto Thaw;
} }
error = disable_nonboot_cpus();
if (error)
goto Enable_cpus;
if (pm_disk_mode == PM_DISK_TEST) { if (pm_disk_mode == PM_DISK_TEST) {
printk("swsusp debug: Waiting for 5 seconds.\n"); printk("swsusp debug: Waiting for 5 seconds.\n");
mdelay(5000); mdelay(5000);
goto Done; goto Enable_cpus;
} }
pr_debug("PM: snapshotting memory.\n"); pr_debug("PM: snapshotting memory.\n");
in_suspend = 1; in_suspend = 1;
if ((error = swsusp_suspend())) error = swsusp_suspend();
goto Done; if (error)
goto Enable_cpus;
if (in_suspend) { if (in_suspend) {
enable_nonboot_cpus();
platform_finish();
device_resume(); device_resume();
resume_console(); resume_console();
pr_debug("PM: writing image.\n"); pr_debug("PM: writing image.\n");
...@@ -188,7 +176,10 @@ int pm_suspend_disk(void) ...@@ -188,7 +176,10 @@ int pm_suspend_disk(void)
} }
swsusp_free(); swsusp_free();
Done: Enable_cpus:
enable_nonboot_cpus();
Resume_devices:
platform_finish();
device_resume(); device_resume();
resume_console(); resume_console();
Thaw: Thaw:
...@@ -237,19 +228,28 @@ static int software_resume(void) ...@@ -237,19 +228,28 @@ static int software_resume(void)
pr_debug("PM: Checking swsusp image.\n"); pr_debug("PM: Checking swsusp image.\n");
if ((error = swsusp_check())) error = swsusp_check();
if (error)
goto Done; goto Done;
pr_debug("PM: Preparing processes for restore.\n"); pr_debug("PM: Preparing processes for restore.\n");
if ((error = prepare_processes())) { error = prepare_processes();
if (error) {
swsusp_close(); swsusp_close();
goto Done; goto Done;
} }
error = platform_prepare();
if (error) {
swsusp_free();
goto Thaw;
}
pr_debug("PM: Reading swsusp image.\n"); pr_debug("PM: Reading swsusp image.\n");
if ((error = swsusp_read())) { error = swsusp_read();
if (error) {
swsusp_free(); swsusp_free();
goto Thaw; goto Thaw;
} }
...@@ -257,21 +257,22 @@ static int software_resume(void) ...@@ -257,21 +257,22 @@ static int software_resume(void)
pr_debug("PM: Preparing devices for restore.\n"); pr_debug("PM: Preparing devices for restore.\n");
suspend_console(); suspend_console();
if ((error = device_suspend(PMSG_PRETHAW))) { error = device_suspend(PMSG_PRETHAW);
resume_console(); if (error)
printk("Some devices failed to suspend\n"); goto Free;
swsusp_free();
goto Thaw;
}
mb(); error = disable_nonboot_cpus();
if (!error)
swsusp_resume();
pr_debug("PM: Restoring saved image.\n"); enable_nonboot_cpus();
swsusp_resume(); Free:
pr_debug("PM: Restore failed, recovering.n"); swsusp_free();
platform_finish();
device_resume(); device_resume();
resume_console(); resume_console();
Thaw: Thaw:
printk(KERN_ERR "PM: Restore failed, recovering.\n");
unprepare_processes(); unprepare_processes();
Done: Done:
/* For success case, the suspend path will release the lock */ /* For success case, the suspend path will release the lock */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment