aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r--kernel/power/disk.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 47882bfa610e..fa3b43b7206d 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -54,7 +54,8 @@ static struct hibernation_ops *hibernation_ops;
54 54
55void hibernation_set_ops(struct hibernation_ops *ops) 55void hibernation_set_ops(struct hibernation_ops *ops)
56{ 56{
57 if (ops && !(ops->prepare && ops->enter && ops->finish)) { 57 if (ops && !(ops->prepare && ops->enter && ops->finish
58 && ops->pre_restore && ops->restore_cleanup)) {
58 WARN_ON(1); 59 WARN_ON(1);
59 return; 60 return;
60 } 61 }
@@ -92,6 +93,31 @@ static void platform_finish(int platform_mode)
92} 93}
93 94
94/** 95/**
96 * platform_pre_restore - prepare the platform for the restoration from a
97 * hibernation image. If the restore fails after this function has been
98 * called, platform_restore_cleanup() must be called.
99 */
100
101static int platform_pre_restore(int platform_mode)
102{
103 return (platform_mode && hibernation_ops) ?
104 hibernation_ops->pre_restore() : 0;
105}
106
107/**
108 * platform_restore_cleanup - switch the platform to the normal mode of
109 * operation after a failing restore. If platform_pre_restore() has been
110 * called before the failing restore, this function must be called too,
111 * regardless of the result of platform_pre_restore().
112 */
113
114static void platform_restore_cleanup(int platform_mode)
115{
116 if (platform_mode && hibernation_ops)
117 hibernation_ops->restore_cleanup();
118}
119
120/**
95 * hibernation_snapshot - quiesce devices and create the hibernation 121 * hibernation_snapshot - quiesce devices and create the hibernation
96 * snapshot image. 122 * snapshot image.
97 * @platform_mode - if set, use the platform driver, if available, to 123 * @platform_mode - if set, use the platform driver, if available, to
@@ -141,11 +167,13 @@ int hibernation_snapshot(int platform_mode)
141/** 167/**
142 * hibernation_restore - quiesce devices and restore the hibernation 168 * hibernation_restore - quiesce devices and restore the hibernation
143 * snapshot image. If successful, control returns in hibernation_snaphot() 169 * snapshot image. If successful, control returns in hibernation_snaphot()
170 * @platform_mode - if set, use the platform driver, if available, to
171 * prepare the platform frimware for the transition.
144 * 172 *
145 * Must be called with pm_mutex held 173 * Must be called with pm_mutex held
146 */ 174 */
147 175
148int hibernation_restore(void) 176int hibernation_restore(int platform_mode)
149{ 177{
150 int error; 178 int error;
151 179
@@ -155,11 +183,14 @@ int hibernation_restore(void)
155 if (error) 183 if (error)
156 goto Finish; 184 goto Finish;
157 185
158 error = disable_nonboot_cpus(); 186 error = platform_pre_restore(platform_mode);
159 if (!error) 187 if (!error) {
160 error = swsusp_resume(); 188 error = disable_nonboot_cpus();
161 189 if (!error)
162 enable_nonboot_cpus(); 190 error = swsusp_resume();
191 enable_nonboot_cpus();
192 }
193 platform_restore_cleanup(platform_mode);
163 Finish: 194 Finish:
164 device_resume(); 195 device_resume();
165 resume_console(); 196 resume_console();
@@ -260,8 +291,12 @@ int hibernate(void)
260 } 291 }
261 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); 292 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
262 if (in_suspend && !error) { 293 if (in_suspend && !error) {
294 unsigned int flags = 0;
295
296 if (hibernation_mode == HIBERNATION_PLATFORM)
297 flags |= SF_PLATFORM_MODE;
263 pr_debug("PM: writing image.\n"); 298 pr_debug("PM: writing image.\n");
264 error = swsusp_write(); 299 error = swsusp_write(flags);
265 swsusp_free(); 300 swsusp_free();
266 if (!error) 301 if (!error)
267 power_down(); 302 power_down();
@@ -295,6 +330,7 @@ int hibernate(void)
295static int software_resume(void) 330static int software_resume(void)
296{ 331{
297 int error; 332 int error;
333 unsigned int flags;
298 334
299 mutex_lock(&pm_mutex); 335 mutex_lock(&pm_mutex);
300 if (!swsusp_resume_device) { 336 if (!swsusp_resume_device) {
@@ -342,9 +378,9 @@ static int software_resume(void)
342 378
343 pr_debug("PM: Reading swsusp image.\n"); 379 pr_debug("PM: Reading swsusp image.\n");
344 380
345 error = swsusp_read(); 381 error = swsusp_read(&flags);
346 if (!error) 382 if (!error)
347 hibernation_restore(); 383 hibernation_restore(flags & SF_PLATFORM_MODE);
348 384
349 printk(KERN_ERR "PM: Restore failed, recovering.\n"); 385 printk(KERN_ERR "PM: Restore failed, recovering.\n");
350 swsusp_free(); 386 swsusp_free();