[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: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ed746e3b18
commit
259130526c
|
@ -122,6 +122,59 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
|
||||||
return res;
|
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,
|
static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
|
@ -145,14 +198,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
||||||
if (data->frozen)
|
if (data->frozen)
|
||||||
break;
|
break;
|
||||||
mutex_lock(&pm_mutex);
|
mutex_lock(&pm_mutex);
|
||||||
error = disable_nonboot_cpus();
|
if (freeze_processes()) {
|
||||||
if (!error) {
|
thaw_processes();
|
||||||
error = freeze_processes();
|
error = -EBUSY;
|
||||||
if (error) {
|
|
||||||
thaw_processes();
|
|
||||||
enable_nonboot_cpus();
|
|
||||||
error = -EBUSY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&pm_mutex);
|
mutex_unlock(&pm_mutex);
|
||||||
if (!error)
|
if (!error)
|
||||||
|
@ -164,7 +212,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
||||||
break;
|
break;
|
||||||
mutex_lock(&pm_mutex);
|
mutex_lock(&pm_mutex);
|
||||||
thaw_processes();
|
thaw_processes();
|
||||||
enable_nonboot_cpus();
|
|
||||||
mutex_unlock(&pm_mutex);
|
mutex_unlock(&pm_mutex);
|
||||||
data->frozen = 0;
|
data->frozen = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -174,20 +221,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
||||||
error = -EPERM;
|
error = -EPERM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_lock(&pm_mutex);
|
error = snapshot_suspend();
|
||||||
/* 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);
|
|
||||||
if (!error)
|
if (!error)
|
||||||
error = put_user(in_suspend, (unsigned int __user *)arg);
|
error = put_user(in_suspend, (unsigned int __user *)arg);
|
||||||
if (!error)
|
if (!error)
|
||||||
|
@ -201,17 +235,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
|
||||||
error = -EPERM;
|
error = -EPERM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_lock(&pm_mutex);
|
error = snapshot_restore();
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SNAPSHOT_FREE:
|
case SNAPSHOT_FREE:
|
||||||
|
|
Loading…
Reference in New Issue