[PATCH] uswsusp: add pmops->{prepare,enter,finish} support (aka "platform mode")
Stefan Seyfried [Thu, 7 Dec 2006 04:34:06 +0000 (20:34 -0800)]
Add an ioctl to the userspace swsusp code that enables the usage of the
pmops->prepare, pmops->enter and pmops->finish methods (the in-kernel
suspend knows these as "platform method").  These are needed on many
machines to (among others) speed up resuming by letting the BIOS skip some
steps or let my hp nx5000 recognise the correct ac_adapter state after
resume again.

It also ensures on many machines, that changed hardware (unplugged AC
adapters) gets correctly detected and that kacpid does not run wild after
resume.

Signed-off-by: Stefan Seyfried <seife@suse.de>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

kernel/power/power.h
kernel/power/user.c

index bfe999f..87ecb18 100644 (file)
@@ -117,7 +117,12 @@ extern void snapshot_free_unused_memory(struct snapshot_handle *handle);
 #define SNAPSHOT_FREE_SWAP_PAGES       _IO(SNAPSHOT_IOC_MAGIC, 9)
 #define SNAPSHOT_SET_SWAP_FILE         _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int)
 #define SNAPSHOT_S2RAM                 _IO(SNAPSHOT_IOC_MAGIC, 11)
-#define SNAPSHOT_IOC_MAXNR     11
+#define SNAPSHOT_PMOPS                 _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int)
+#define SNAPSHOT_IOC_MAXNR     12
+
+#define PMOPS_PREPARE  1
+#define PMOPS_ENTER    2
+#define PMOPS_FINISH   3
 
 /**
  *     The bitmap is used for tracing allocated swap pages
index d991d3b..4c24ca5 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/suspend.h>
 #include <linux/syscalls.h>
+#include <linux/reboot.h>
 #include <linux/string.h>
 #include <linux/device.h>
 #include <linux/miscdevice.h>
@@ -313,6 +314,33 @@ OutS3:
                up(&pm_sem);
                break;
 
+       case SNAPSHOT_PMOPS:
+               switch (arg) {
+
+               case PMOPS_PREPARE:
+                       if (pm_ops->prepare) {
+                               error = pm_ops->prepare(PM_SUSPEND_DISK);
+                       }
+                       break;
+
+               case PMOPS_ENTER:
+                       kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
+                       error = pm_ops->enter(PM_SUSPEND_DISK);
+                       break;
+
+               case PMOPS_FINISH:
+                       if (pm_ops && pm_ops->finish) {
+                               pm_ops->finish(PM_SUSPEND_DISK);
+                       }
+                       break;
+
+               default:
+                       printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);
+                       error = -EINVAL;
+
+               }
+               break;
+
        default:
                error = -ENOTTY;