Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -309,6 +309,8 @@ void enable_nonboot_cpus(void)
	mutex_lock(&cpu_add_remove_lock);
	cpu_hotplug_disabled = 0;
	mutex_unlock(&cpu_add_remove_lock);
	if (cpus_empty(frozen_cpus))
		return;

	printk("Enabling non-boot CPUs ...\n");
	for_each_cpu_mask(cpu, frozen_cpus) {
+58 −57
Original line number Diff line number Diff line
@@ -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)
{
	int error = 0;

	pm_prepare_console();

	error = disable_nonboot_cpus();
	if (error)
		goto enable_cpus;

	if (freeze_processes()) {
		error = -EBUSY;
		goto thaw;
	}

	if (pm_disk_mode == PM_DISK_TESTPROC) {
		printk("swsusp debug: Waiting for 5 seconds.\n");
		mdelay(5000);
		goto thaw;
		unprepare_processes();
	}

	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;
}

static void unprepare_processes(void)
{
	platform_finish();
	thaw_processes();
	enable_nonboot_cpus();
	pm_restore_console();
}

/**
 *	pm_suspend_disk - The granpappy of hibernation power management.
 *
@@ -150,29 +122,45 @@ int pm_suspend_disk(void)
	if (error)
		return error;

	if (pm_disk_mode == PM_DISK_TESTPROC)
		return 0;
	if (pm_disk_mode == PM_DISK_TESTPROC) {
		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();
	error = device_suspend(PMSG_FREEZE);
	if (error) {
		resume_console();
		printk("Some devices failed to suspend\n");
		goto Thaw;
		printk(KERN_ERR "PM: Some devices failed to suspend\n");
		goto Resume_devices;
	}
	error = disable_nonboot_cpus();
	if (error)
		goto Enable_cpus;

	if (pm_disk_mode == PM_DISK_TEST) {
		printk("swsusp debug: Waiting for 5 seconds.\n");
		mdelay(5000);
		goto Done;
		goto Enable_cpus;
	}

	pr_debug("PM: snapshotting memory.\n");
	in_suspend = 1;
	if ((error = swsusp_suspend()))
		goto Done;
	error = swsusp_suspend();
	if (error)
		goto Enable_cpus;

	if (in_suspend) {
		enable_nonboot_cpus();
		platform_finish();
		device_resume();
		resume_console();
		pr_debug("PM: writing image.\n");
@@ -188,7 +176,10 @@ int pm_suspend_disk(void)
	}

	swsusp_free();
 Done:
 Enable_cpus:
	enable_nonboot_cpus();
 Resume_devices:
	platform_finish();
	device_resume();
	resume_console();
 Thaw:
@@ -237,41 +228,51 @@ static int software_resume(void)

	pr_debug("PM: Checking swsusp image.\n");

	if ((error = swsusp_check()))
	error = swsusp_check();
	if (error)
		goto Done;

	pr_debug("PM: Preparing processes for restore.\n");

	if ((error = prepare_processes())) {
	error = prepare_processes();
	if (error) {
		swsusp_close();
		goto Done;
	}

	pr_debug("PM: Reading swsusp image.\n");

	if ((error = swsusp_read())) {
	error = platform_prepare();
	if (error) {
		swsusp_free();
		goto Thaw;
	}

	pr_debug("PM: Preparing devices for restore.\n");
	pr_debug("PM: Reading swsusp image.\n");

	suspend_console();
	if ((error = device_suspend(PMSG_PRETHAW))) {
		resume_console();
		printk("Some devices failed to suspend\n");
	error = swsusp_read();
	if (error) {
		swsusp_free();
		goto Thaw;
	}

	mb();
	pr_debug("PM: Preparing devices for restore.\n");

	pr_debug("PM: Restoring saved image.\n");
	suspend_console();
	error = device_suspend(PMSG_PRETHAW);
	if (error)
		goto Free;

	error = disable_nonboot_cpus();
	if (!error)
		swsusp_resume();
	pr_debug("PM: Restore failed, recovering.n");

	enable_nonboot_cpus();
 Free:
	swsusp_free();
	platform_finish();
	device_resume();
	resume_console();
 Thaw:
	printk(KERN_ERR "PM: Restore failed, recovering.\n");
	unprepare_processes();
 Done:
	/* For success case, the suspend path will release the lock */