Skip to content

Commit

Permalink
[PATCH] swsusp: Change pm_ops handling by userland interface
Browse files Browse the repository at this point in the history
Make the userland interface of swsusp call pm_ops->finish() after
enable_nonboot_cpus() and before resume_device(), as indicated by the recent
discussion on Linux-PM (cf.
http://lists.osdl.org/pipermail/linux-pm/2006-November/004164.html).

This patch changes the SNAPSHOT_PMOPS ioctl so that its first function,
PMOPS_PREPARE, only sets a switch turning the platform suspend mode on, and
its last function, PMOPS_FINISH, only checks if the platform mode is enabled.
This should allow the older userland tools to work with new kernels without
any modifications.

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>
  • Loading branch information
Rafael J. Wysocki authored and Linus Torvalds committed Feb 11, 2007
1 parent d12c610 commit 2b5b09b
Showing 1 changed file with 59 additions and 12 deletions.
71 changes: 59 additions & 12 deletions kernel/power/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ static struct snapshot_data {
int mode;
char frozen;
char ready;
char platform_suspend;
} snapshot_state;

static atomic_t device_available = ATOMIC_INIT(1);
Expand Down Expand Up @@ -66,6 +67,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
data->bitmap = NULL;
data->frozen = 0;
data->ready = 0;
data->platform_suspend = 0;

return 0;
}
Expand Down Expand Up @@ -122,7 +124,23 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
return res;
}

static int snapshot_suspend(void)
static inline int platform_prepare(void)
{
int error = 0;

if (pm_ops && pm_ops->prepare)
error = pm_ops->prepare(PM_SUSPEND_DISK);

return error;
}

static inline void platform_finish(void)
{
if (pm_ops && pm_ops->finish)
pm_ops->finish(PM_SUSPEND_DISK);
}

static inline int snapshot_suspend(int platform_suspend)
{
int error;

Expand All @@ -132,6 +150,11 @@ static int snapshot_suspend(void)
if (error)
goto Finish;

if (platform_suspend) {
error = platform_prepare();
if (error)
goto Finish;
}
suspend_console();
error = device_suspend(PMSG_FREEZE);
if (error)
Expand All @@ -144,19 +167,27 @@ static int snapshot_suspend(void)
}
enable_nonboot_cpus();
Resume_devices:
if (platform_suspend)
platform_finish();

device_resume();
resume_console();
Finish:
mutex_unlock(&pm_mutex);
return error;
}

static int snapshot_restore(void)
static inline int snapshot_restore(int platform_suspend)
{
int error;

mutex_lock(&pm_mutex);
pm_prepare_console();
if (platform_suspend) {
error = platform_prepare();
if (error)
goto Finish;
}
suspend_console();
error = device_suspend(PMSG_PRETHAW);
if (error)
Expand All @@ -168,8 +199,12 @@ static int snapshot_restore(void)

enable_nonboot_cpus();
Resume_devices:
if (platform_suspend)
platform_finish();

device_resume();
resume_console();
Finish:
pm_restore_console();
mutex_unlock(&pm_mutex);
return error;
Expand Down Expand Up @@ -221,7 +256,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -EPERM;
break;
}
error = snapshot_suspend();
error = snapshot_suspend(data->platform_suspend);
if (!error)
error = put_user(in_suspend, (unsigned int __user *)arg);
if (!error)
Expand All @@ -235,7 +270,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -EPERM;
break;
}
error = snapshot_restore();
error = snapshot_restore(data->platform_suspend);
break;

case SNAPSHOT_FREE:
Expand Down Expand Up @@ -306,6 +341,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
break;

case SNAPSHOT_S2RAM:
if (!pm_ops) {
error = -ENOSYS;
break;
}

if (!data->frozen) {
error = -EPERM;
break;
Expand Down Expand Up @@ -343,28 +383,35 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
break;

case SNAPSHOT_PMOPS:
error = -EINVAL;

switch (arg) {

case PMOPS_PREPARE:
if (pm_ops->prepare) {
error = pm_ops->prepare(PM_SUSPEND_DISK);
if (pm_ops && pm_ops->enter) {
data->platform_suspend = 1;
error = 0;
} else {
error = -ENOSYS;
}
break;

case PMOPS_ENTER:
kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
error = pm_ops->enter(PM_SUSPEND_DISK);
if (data->platform_suspend) {
kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
error = pm_ops->enter(PM_SUSPEND_DISK);
error = 0;
}
break;

case PMOPS_FINISH:
if (pm_ops && pm_ops->finish) {
pm_ops->finish(PM_SUSPEND_DISK);
}
if (data->platform_suspend)
error = 0;

break;

default:
printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);
error = -EINVAL;

}
break;
Expand Down

0 comments on commit 2b5b09b

Please sign in to comment.