apm-emulation: add hibernation APM events to support suspend2disk
authorBin Shi <Bin.Shi@csr.com>
Fri, 3 Jan 2014 06:08:54 +0000 (14:08 +0800)
committerJiri Kosina <jkosina@suse.cz>
Tue, 7 Jan 2014 12:50:28 +0000 (13:50 +0100)
Some embedded systems use hibernation for fast boot. and in it,
some software components need to handle specific things before
hibernation and after restore. So it needs to capture the apm
status about these pm events.

Currently apm just supports suspend to ram, but not suspend to disk,
so here add logic about hibernation apm events.

Signed-off-by: Bin Shi <Bin.Shi@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/char/apm-emulation.c
include/uapi/linux/apm_bios.h

index 46118f8459484a35c3a709c12a28512fd56820af..dd9dfa15e9d13364b1ce2ea65de957bdd21a6ee4 100644 (file)
@@ -531,6 +531,7 @@ static int apm_suspend_notifier(struct notifier_block *nb,
 {
        struct apm_user *as;
        int err;
+       unsigned long apm_event;
 
        /* short-cut emergency suspends */
        if (atomic_read(&userspace_notification_inhibit))
@@ -538,6 +539,9 @@ static int apm_suspend_notifier(struct notifier_block *nb,
 
        switch (event) {
        case PM_SUSPEND_PREPARE:
+       case PM_HIBERNATION_PREPARE:
+               apm_event = (event == PM_SUSPEND_PREPARE) ?
+                       APM_USER_SUSPEND : APM_USER_HIBERNATION;
                /*
                 * Queue an event to all "writer" users that we want
                 * to suspend and need their ack.
@@ -550,7 +554,7 @@ static int apm_suspend_notifier(struct notifier_block *nb,
                            as->writer && as->suser) {
                                as->suspend_state = SUSPEND_PENDING;
                                atomic_inc(&suspend_acks_pending);
-                               queue_add_event(&as->queue, APM_USER_SUSPEND);
+                               queue_add_event(&as->queue, apm_event);
                        }
                }
 
@@ -601,11 +605,14 @@ static int apm_suspend_notifier(struct notifier_block *nb,
                return notifier_from_errno(err);
 
        case PM_POST_SUSPEND:
+       case PM_POST_HIBERNATION:
+               apm_event = (event == PM_POST_SUSPEND) ?
+                       APM_NORMAL_RESUME : APM_HIBERNATION_RESUME;
                /*
                 * Anyone on the APM queues will think we're still suspended.
                 * Send a message so everyone knows we're now awake again.
                 */
-               queue_event(APM_NORMAL_RESUME);
+               queue_event(apm_event);
 
                /*
                 * Finally, wake up anyone who is sleeping on the suspend.
index 724f409adae025fffb464c43638a024da030be96..df79bca1b8987474aadc7f389d2f39b2068665c0 100644 (file)
@@ -67,6 +67,8 @@ struct apm_bios_info {
 #define APM_USER_SUSPEND       0x000a
 #define APM_STANDBY_RESUME     0x000b
 #define APM_CAPABILITY_CHANGE  0x000c
+#define APM_USER_HIBERNATION   0x000d
+#define APM_HIBERNATION_RESUME 0x000e
 
 /*
  * Error codes