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

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

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

Change the ordering of code in kernel/power/user.c so that device_suspend() is
called before disable_nonboot_cpus() and device_resume() is called after
enable_nonboot_cpus().  This is needed to make the userland suspend call
pm_ops->finish() 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 userland interface of swsusp.

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>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ed746e3b
Loading
Loading
Loading
Loading
+58 −34
Original line number Diff line number Diff line
@@ -122,6 +122,59 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
	return res;
}

static inline int snapshot_suspend(void)
{
	int error;

	mutex_lock(&pm_mutex);
	/* Free memory before shutting down devices. */
	error = swsusp_shrink_memory();
	if (error)
		goto Finish;

	suspend_console();
	error = device_suspend(PMSG_FREEZE);
	if (error)
		goto Resume_devices;

	error = disable_nonboot_cpus();
	if (!error) {
		in_suspend = 1;
		error = swsusp_suspend();
	}
	enable_nonboot_cpus();
 Resume_devices:
	device_resume();
	resume_console();
 Finish:
	mutex_unlock(&pm_mutex);
	return error;
}

static inline int snapshot_restore(void)
{
	int error;

	mutex_lock(&pm_mutex);
	pm_prepare_console();
	suspend_console();
	error = device_suspend(PMSG_PRETHAW);
	if (error)
		goto Resume_devices;

	error = disable_nonboot_cpus();
	if (!error)
		error = swsusp_resume();

	enable_nonboot_cpus();
 Resume_devices:
	device_resume();
	resume_console();
	pm_restore_console();
	mutex_unlock(&pm_mutex);
	return error;
}

static int snapshot_ioctl(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg)
{
@@ -145,15 +198,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
		if (data->frozen)
			break;
		mutex_lock(&pm_mutex);
		error = disable_nonboot_cpus();
		if (!error) {
			error = freeze_processes();
			if (error) {
		if (freeze_processes()) {
			thaw_processes();
				enable_nonboot_cpus();
			error = -EBUSY;
		}
		}
		mutex_unlock(&pm_mutex);
		if (!error)
			data->frozen = 1;
@@ -164,7 +212,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
			break;
		mutex_lock(&pm_mutex);
		thaw_processes();
		enable_nonboot_cpus();
		mutex_unlock(&pm_mutex);
		data->frozen = 0;
		break;
@@ -174,20 +221,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
			error = -EPERM;
			break;
		}
		mutex_lock(&pm_mutex);
		/* Free memory before shutting down devices. */
		error = swsusp_shrink_memory();
		if (!error) {
			suspend_console();
			error = device_suspend(PMSG_FREEZE);
			if (!error) {
				in_suspend = 1;
				error = swsusp_suspend();
				device_resume();
			}
			resume_console();
		}
		mutex_unlock(&pm_mutex);
		error = snapshot_suspend();
		if (!error)
			error = put_user(in_suspend, (unsigned int __user *)arg);
		if (!error)
@@ -201,17 +235,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
			error = -EPERM;
			break;
		}
		mutex_lock(&pm_mutex);
		pm_prepare_console();
		suspend_console();
		error = device_suspend(PMSG_PRETHAW);
		if (!error) {
			error = swsusp_resume();
			device_resume();
		}
		resume_console();
		pm_restore_console();
		mutex_unlock(&pm_mutex);
		error = snapshot_restore();
		break;

	case SNAPSHOT_FREE: