aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-11-19 17:38:25 -0500
committerLen Brown <len.brown@intel.com>2008-02-01 18:30:53 -0500
commitc3e94d899c864e558f938f9845ddb8c2e5d5ccd0 (patch)
treecdc2d5007e2d8053ab1903f9e66c46dca9a9de81
parent2f8ed1c60b06b797bf79a1dc540f0bed8c9d75a0 (diff)
Hibernation: Add PM_RESTORE_PREPARE and PM_POST_RESTORE notifiers (rev. 2)
Add PM_RESTORE_PREPARE and PM_POST_RESTORE notifiers to the PM core, to be used in analogy with the existing PM_HIBERNATION_PREPARE and PM_POST_HIBERNATION notifiers. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--Documentation/power/notifiers.txt8
-rw-r--r--include/linux/notifier.h2
-rw-r--r--kernel/power/disk.c5
-rw-r--r--kernel/power/user.c31
4 files changed, 34 insertions, 12 deletions
diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt
index 9293e4bc857c..ae1b7ec07684 100644
--- a/Documentation/power/notifiers.txt
+++ b/Documentation/power/notifiers.txt
@@ -28,6 +28,14 @@ PM_POST_HIBERNATION The system memory state has been restored from a
28 hibernation. Device drivers' .resume() callbacks have 28 hibernation. Device drivers' .resume() callbacks have
29 been executed and tasks have been thawed. 29 been executed and tasks have been thawed.
30 30
31PM_RESTORE_PREPARE The system is going to restore a hibernation image.
32 If all goes well the restored kernel will issue a
33 PM_POST_HIBERNATION notification.
34
35PM_POST_RESTORE An error occurred during the hibernation restore.
36 Device drivers' .resume() callbacks have been executed
37 and tasks have been thawed.
38
31PM_SUSPEND_PREPARE The system is preparing for a suspend. 39PM_SUSPEND_PREPARE The system is preparing for a suspend.
32 40
33PM_POST_SUSPEND The system has just resumed or an error occured during 41PM_POST_SUSPEND The system has just resumed or an error occured during
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 5dfbc684ce7d..f4df40038f0c 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -228,6 +228,8 @@ static inline int notifier_to_errno(int ret)
228#define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */ 228#define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */
229#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */ 229#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */
230#define PM_POST_SUSPEND 0x0004 /* Suspend finished */ 230#define PM_POST_SUSPEND 0x0004 /* Suspend finished */
231#define PM_RESTORE_PREPARE 0x0005 /* Going to restore a saved image */
232#define PM_POST_RESTORE 0x0006 /* Restore failed */
231 233
232/* Console keyboard events. 234/* Console keyboard events.
233 * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and 235 * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index b138b431e271..659736508239 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -499,6 +499,10 @@ static int software_resume(void)
499 goto Unlock; 499 goto Unlock;
500 } 500 }
501 501
502 error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
503 if (error)
504 goto Finish;
505
502 error = create_basic_memory_bitmaps(); 506 error = create_basic_memory_bitmaps();
503 if (error) 507 if (error)
504 goto Finish; 508 goto Finish;
@@ -522,6 +526,7 @@ static int software_resume(void)
522 Done: 526 Done:
523 free_basic_memory_bitmaps(); 527 free_basic_memory_bitmaps();
524 Finish: 528 Finish:
529 pm_notifier_call_chain(PM_POST_RESTORE);
525 atomic_inc(&snapshot_device_available); 530 atomic_inc(&snapshot_device_available);
526 /* For success case, the suspend path will release the lock */ 531 /* For success case, the suspend path will release the lock */
527 Unlock: 532 Unlock:
diff --git a/kernel/power/user.c b/kernel/power/user.c
index b902a7e3bd12..f5512cb3aa86 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -67,6 +67,7 @@ atomic_t snapshot_device_available = ATOMIC_INIT(1);
67static int snapshot_open(struct inode *inode, struct file *filp) 67static int snapshot_open(struct inode *inode, struct file *filp)
68{ 68{
69 struct snapshot_data *data; 69 struct snapshot_data *data;
70 int error;
70 71
71 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) 72 if (!atomic_add_unless(&snapshot_device_available, -1, 0))
72 return -EBUSY; 73 return -EBUSY;
@@ -87,9 +88,19 @@ static int snapshot_open(struct inode *inode, struct file *filp)
87 data->swap = swsusp_resume_device ? 88 data->swap = swsusp_resume_device ?
88 swap_type_of(swsusp_resume_device, 0, NULL) : -1; 89 swap_type_of(swsusp_resume_device, 0, NULL) : -1;
89 data->mode = O_RDONLY; 90 data->mode = O_RDONLY;
91 error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
92 if (error)
93 pm_notifier_call_chain(PM_POST_RESTORE);
90 } else { 94 } else {
91 data->swap = -1; 95 data->swap = -1;
92 data->mode = O_WRONLY; 96 data->mode = O_WRONLY;
97 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
98 if (error)
99 pm_notifier_call_chain(PM_POST_HIBERNATION);
100 }
101 if (error) {
102 atomic_inc(&snapshot_device_available);
103 return error;
93 } 104 }
94 data->frozen = 0; 105 data->frozen = 0;
95 data->ready = 0; 106 data->ready = 0;
@@ -111,6 +122,8 @@ static int snapshot_release(struct inode *inode, struct file *filp)
111 thaw_processes(); 122 thaw_processes();
112 mutex_unlock(&pm_mutex); 123 mutex_unlock(&pm_mutex);
113 } 124 }
125 pm_notifier_call_chain(data->mode == O_WRONLY ?
126 PM_POST_HIBERNATION : PM_POST_RESTORE);
114 atomic_inc(&snapshot_device_available); 127 atomic_inc(&snapshot_device_available);
115 return 0; 128 return 0;
116} 129}
@@ -174,18 +187,13 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
174 if (data->frozen) 187 if (data->frozen)
175 break; 188 break;
176 mutex_lock(&pm_mutex); 189 mutex_lock(&pm_mutex);
177 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); 190 printk("Syncing filesystems ... ");
178 if (!error) { 191 sys_sync();
179 printk("Syncing filesystems ... "); 192 printk("done.\n");
180 sys_sync(); 193
181 printk("done.\n"); 194 error = freeze_processes();
182
183 error = freeze_processes();
184 if (error)
185 thaw_processes();
186 }
187 if (error) 195 if (error)
188 pm_notifier_call_chain(PM_POST_HIBERNATION); 196 thaw_processes();
189 mutex_unlock(&pm_mutex); 197 mutex_unlock(&pm_mutex);
190 if (!error) 198 if (!error)
191 data->frozen = 1; 199 data->frozen = 1;
@@ -196,7 +204,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
196 break; 204 break;
197 mutex_lock(&pm_mutex); 205 mutex_lock(&pm_mutex);
198 thaw_processes(); 206 thaw_processes();
199 pm_notifier_call_chain(PM_POST_HIBERNATION);
200 mutex_unlock(&pm_mutex); 207 mutex_unlock(&pm_mutex);
201 data->frozen = 0; 208 data->frozen = 0;
202 break; 209 break;