diff options
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r-- | kernel/power/hibernate.c | 331 |
1 files changed, 191 insertions, 140 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 8dc31e02ae12..8f7b1db1ece1 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
@@ -23,12 +23,13 @@ | |||
23 | #include <linux/cpu.h> | 23 | #include <linux/cpu.h> |
24 | #include <linux/freezer.h> | 24 | #include <linux/freezer.h> |
25 | #include <linux/gfp.h> | 25 | #include <linux/gfp.h> |
26 | #include <linux/syscore_ops.h> | ||
26 | #include <scsi/scsi_scan.h> | 27 | #include <scsi/scsi_scan.h> |
27 | #include <asm/suspend.h> | ||
28 | 28 | ||
29 | #include "power.h" | 29 | #include "power.h" |
30 | 30 | ||
31 | 31 | ||
32 | static int nocompress = 0; | ||
32 | static int noresume = 0; | 33 | static int noresume = 0; |
33 | static char resume_file[256] = CONFIG_PM_STD_PARTITION; | 34 | static char resume_file[256] = CONFIG_PM_STD_PARTITION; |
34 | dev_t swsusp_resume_device; | 35 | dev_t swsusp_resume_device; |
@@ -50,18 +51,17 @@ enum { | |||
50 | 51 | ||
51 | static int hibernation_mode = HIBERNATION_SHUTDOWN; | 52 | static int hibernation_mode = HIBERNATION_SHUTDOWN; |
52 | 53 | ||
53 | static struct platform_hibernation_ops *hibernation_ops; | 54 | static const struct platform_hibernation_ops *hibernation_ops; |
54 | 55 | ||
55 | /** | 56 | /** |
56 | * hibernation_set_ops - set the global hibernate operations | 57 | * hibernation_set_ops - Set the global hibernate operations. |
57 | * @ops: the hibernation operations to use in subsequent hibernation transitions | 58 | * @ops: Hibernation operations to use in subsequent hibernation transitions. |
58 | */ | 59 | */ |
59 | 60 | void hibernation_set_ops(const struct platform_hibernation_ops *ops) | |
60 | void hibernation_set_ops(struct platform_hibernation_ops *ops) | ||
61 | { | 61 | { |
62 | if (ops && !(ops->begin && ops->end && ops->pre_snapshot | 62 | if (ops && !(ops->begin && ops->end && ops->pre_snapshot |
63 | && ops->prepare && ops->finish && ops->enter && ops->pre_restore | 63 | && ops->prepare && ops->finish && ops->enter && ops->pre_restore |
64 | && ops->restore_cleanup)) { | 64 | && ops->restore_cleanup && ops->leave)) { |
65 | WARN_ON(1); | 65 | WARN_ON(1); |
66 | return; | 66 | return; |
67 | } | 67 | } |
@@ -113,10 +113,9 @@ static int hibernation_test(int level) { return 0; } | |||
113 | #endif /* !CONFIG_PM_DEBUG */ | 113 | #endif /* !CONFIG_PM_DEBUG */ |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * platform_begin - tell the platform driver that we're starting | 116 | * platform_begin - Call platform to start hibernation. |
117 | * hibernation | 117 | * @platform_mode: Whether or not to use the platform driver. |
118 | */ | 118 | */ |
119 | |||
120 | static int platform_begin(int platform_mode) | 119 | static int platform_begin(int platform_mode) |
121 | { | 120 | { |
122 | return (platform_mode && hibernation_ops) ? | 121 | return (platform_mode && hibernation_ops) ? |
@@ -124,10 +123,9 @@ static int platform_begin(int platform_mode) | |||
124 | } | 123 | } |
125 | 124 | ||
126 | /** | 125 | /** |
127 | * platform_end - tell the platform driver that we've entered the | 126 | * platform_end - Call platform to finish transition to the working state. |
128 | * working state | 127 | * @platform_mode: Whether or not to use the platform driver. |
129 | */ | 128 | */ |
130 | |||
131 | static void platform_end(int platform_mode) | 129 | static void platform_end(int platform_mode) |
132 | { | 130 | { |
133 | if (platform_mode && hibernation_ops) | 131 | if (platform_mode && hibernation_ops) |
@@ -135,8 +133,11 @@ static void platform_end(int platform_mode) | |||
135 | } | 133 | } |
136 | 134 | ||
137 | /** | 135 | /** |
138 | * platform_pre_snapshot - prepare the machine for hibernation using the | 136 | * platform_pre_snapshot - Call platform to prepare the machine for hibernation. |
139 | * platform driver if so configured and return an error code if it fails | 137 | * @platform_mode: Whether or not to use the platform driver. |
138 | * | ||
139 | * Use the platform driver to prepare the system for creating a hibernate image, | ||
140 | * if so configured, and return an error code if that fails. | ||
140 | */ | 141 | */ |
141 | 142 | ||
142 | static int platform_pre_snapshot(int platform_mode) | 143 | static int platform_pre_snapshot(int platform_mode) |
@@ -146,10 +147,14 @@ static int platform_pre_snapshot(int platform_mode) | |||
146 | } | 147 | } |
147 | 148 | ||
148 | /** | 149 | /** |
149 | * platform_leave - prepare the machine for switching to the normal mode | 150 | * platform_leave - Call platform to prepare a transition to the working state. |
150 | * of operation using the platform driver (called with interrupts disabled) | 151 | * @platform_mode: Whether or not to use the platform driver. |
152 | * | ||
153 | * Use the platform driver prepare to prepare the machine for switching to the | ||
154 | * normal mode of operation. | ||
155 | * | ||
156 | * This routine is called on one CPU with interrupts disabled. | ||
151 | */ | 157 | */ |
152 | |||
153 | static void platform_leave(int platform_mode) | 158 | static void platform_leave(int platform_mode) |
154 | { | 159 | { |
155 | if (platform_mode && hibernation_ops) | 160 | if (platform_mode && hibernation_ops) |
@@ -157,10 +162,14 @@ static void platform_leave(int platform_mode) | |||
157 | } | 162 | } |
158 | 163 | ||
159 | /** | 164 | /** |
160 | * platform_finish - switch the machine to the normal mode of operation | 165 | * platform_finish - Call platform to switch the system to the working state. |
161 | * using the platform driver (must be called after platform_prepare()) | 166 | * @platform_mode: Whether or not to use the platform driver. |
167 | * | ||
168 | * Use the platform driver to switch the machine to the normal mode of | ||
169 | * operation. | ||
170 | * | ||
171 | * This routine must be called after platform_prepare(). | ||
162 | */ | 172 | */ |
163 | |||
164 | static void platform_finish(int platform_mode) | 173 | static void platform_finish(int platform_mode) |
165 | { | 174 | { |
166 | if (platform_mode && hibernation_ops) | 175 | if (platform_mode && hibernation_ops) |
@@ -168,11 +177,15 @@ static void platform_finish(int platform_mode) | |||
168 | } | 177 | } |
169 | 178 | ||
170 | /** | 179 | /** |
171 | * platform_pre_restore - prepare the platform for the restoration from a | 180 | * platform_pre_restore - Prepare for hibernate image restoration. |
172 | * hibernation image. If the restore fails after this function has been | 181 | * @platform_mode: Whether or not to use the platform driver. |
173 | * called, platform_restore_cleanup() must be called. | 182 | * |
183 | * Use the platform driver to prepare the system for resume from a hibernation | ||
184 | * image. | ||
185 | * | ||
186 | * If the restore fails after this function has been called, | ||
187 | * platform_restore_cleanup() must be called. | ||
174 | */ | 188 | */ |
175 | |||
176 | static int platform_pre_restore(int platform_mode) | 189 | static int platform_pre_restore(int platform_mode) |
177 | { | 190 | { |
178 | return (platform_mode && hibernation_ops) ? | 191 | return (platform_mode && hibernation_ops) ? |
@@ -180,12 +193,16 @@ static int platform_pre_restore(int platform_mode) | |||
180 | } | 193 | } |
181 | 194 | ||
182 | /** | 195 | /** |
183 | * platform_restore_cleanup - switch the platform to the normal mode of | 196 | * platform_restore_cleanup - Switch to the working state after failing restore. |
184 | * operation after a failing restore. If platform_pre_restore() has been | 197 | * @platform_mode: Whether or not to use the platform driver. |
185 | * called before the failing restore, this function must be called too, | 198 | * |
186 | * regardless of the result of platform_pre_restore(). | 199 | * Use the platform driver to switch the system to the normal mode of operation |
200 | * after a failing restore. | ||
201 | * | ||
202 | * If platform_pre_restore() has been called before the failing restore, this | ||
203 | * function must be called too, regardless of the result of | ||
204 | * platform_pre_restore(). | ||
187 | */ | 205 | */ |
188 | |||
189 | static void platform_restore_cleanup(int platform_mode) | 206 | static void platform_restore_cleanup(int platform_mode) |
190 | { | 207 | { |
191 | if (platform_mode && hibernation_ops) | 208 | if (platform_mode && hibernation_ops) |
@@ -193,10 +210,9 @@ static void platform_restore_cleanup(int platform_mode) | |||
193 | } | 210 | } |
194 | 211 | ||
195 | /** | 212 | /** |
196 | * platform_recover - recover the platform from a failure to suspend | 213 | * platform_recover - Recover from a failure to suspend devices. |
197 | * devices. | 214 | * @platform_mode: Whether or not to use the platform driver. |
198 | */ | 215 | */ |
199 | |||
200 | static void platform_recover(int platform_mode) | 216 | static void platform_recover(int platform_mode) |
201 | { | 217 | { |
202 | if (platform_mode && hibernation_ops && hibernation_ops->recover) | 218 | if (platform_mode && hibernation_ops && hibernation_ops->recover) |
@@ -204,13 +220,12 @@ static void platform_recover(int platform_mode) | |||
204 | } | 220 | } |
205 | 221 | ||
206 | /** | 222 | /** |
207 | * swsusp_show_speed - print the time elapsed between two events. | 223 | * swsusp_show_speed - Print time elapsed between two events during hibernation. |
208 | * @start: Starting event. | 224 | * @start: Starting event. |
209 | * @stop: Final event. | 225 | * @stop: Final event. |
210 | * @nr_pages - number of pages processed between @start and @stop | 226 | * @nr_pages: Number of memory pages processed between @start and @stop. |
211 | * @msg - introductory message to print | 227 | * @msg: Additional diagnostic message to print. |
212 | */ | 228 | */ |
213 | |||
214 | void swsusp_show_speed(struct timeval *start, struct timeval *stop, | 229 | void swsusp_show_speed(struct timeval *start, struct timeval *stop, |
215 | unsigned nr_pages, char *msg) | 230 | unsigned nr_pages, char *msg) |
216 | { | 231 | { |
@@ -233,25 +248,18 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop, | |||
233 | } | 248 | } |
234 | 249 | ||
235 | /** | 250 | /** |
236 | * create_image - freeze devices that need to be frozen with interrupts | 251 | * create_image - Create a hibernation image. |
237 | * off, create the hibernation image and thaw those devices. Control | 252 | * @platform_mode: Whether or not to use the platform driver. |
238 | * reappears in this routine after a restore. | 253 | * |
254 | * Execute device drivers' .freeze_noirq() callbacks, create a hibernation image | ||
255 | * and execute the drivers' .thaw_noirq() callbacks. | ||
256 | * | ||
257 | * Control reappears in this routine after the subsequent restore. | ||
239 | */ | 258 | */ |
240 | |||
241 | static int create_image(int platform_mode) | 259 | static int create_image(int platform_mode) |
242 | { | 260 | { |
243 | int error; | 261 | int error; |
244 | 262 | ||
245 | error = arch_prepare_suspend(); | ||
246 | if (error) | ||
247 | return error; | ||
248 | |||
249 | /* At this point, dpm_suspend_start() has been called, but *not* | ||
250 | * dpm_suspend_noirq(). We *must* call dpm_suspend_noirq() now. | ||
251 | * Otherwise, drivers for some devices (e.g. interrupt controllers) | ||
252 | * become desynchronized with the actual state of the hardware | ||
253 | * at resume time, and evil weirdness ensues. | ||
254 | */ | ||
255 | error = dpm_suspend_noirq(PMSG_FREEZE); | 263 | error = dpm_suspend_noirq(PMSG_FREEZE); |
256 | if (error) { | 264 | if (error) { |
257 | printk(KERN_ERR "PM: Some devices failed to power down, " | 265 | printk(KERN_ERR "PM: Some devices failed to power down, " |
@@ -270,14 +278,14 @@ static int create_image(int platform_mode) | |||
270 | 278 | ||
271 | local_irq_disable(); | 279 | local_irq_disable(); |
272 | 280 | ||
273 | error = sysdev_suspend(PMSG_FREEZE); | 281 | error = syscore_suspend(); |
274 | if (error) { | 282 | if (error) { |
275 | printk(KERN_ERR "PM: Some system devices failed to power down, " | 283 | printk(KERN_ERR "PM: Some system devices failed to power down, " |
276 | "aborting hibernation\n"); | 284 | "aborting hibernation\n"); |
277 | goto Enable_irqs; | 285 | goto Enable_irqs; |
278 | } | 286 | } |
279 | 287 | ||
280 | if (hibernation_test(TEST_CORE) || !pm_check_wakeup_events()) | 288 | if (hibernation_test(TEST_CORE) || pm_wakeup_pending()) |
281 | goto Power_up; | 289 | goto Power_up; |
282 | 290 | ||
283 | in_suspend = 1; | 291 | in_suspend = 1; |
@@ -294,10 +302,7 @@ static int create_image(int platform_mode) | |||
294 | } | 302 | } |
295 | 303 | ||
296 | Power_up: | 304 | Power_up: |
297 | sysdev_resume(); | 305 | syscore_resume(); |
298 | /* NOTE: dpm_resume_noirq() is just a resume() for devices | ||
299 | * that suspended with irqs off ... no overall powerup. | ||
300 | */ | ||
301 | 306 | ||
302 | Enable_irqs: | 307 | Enable_irqs: |
303 | local_irq_enable(); | 308 | local_irq_enable(); |
@@ -315,31 +320,32 @@ static int create_image(int platform_mode) | |||
315 | } | 320 | } |
316 | 321 | ||
317 | /** | 322 | /** |
318 | * hibernation_snapshot - quiesce devices and create the hibernation | 323 | * hibernation_snapshot - Quiesce devices and create a hibernation image. |
319 | * snapshot image. | 324 | * @platform_mode: If set, use platform driver to prepare for the transition. |
320 | * @platform_mode - if set, use the platform driver, if available, to | ||
321 | * prepare the platform firmware for the power transition. | ||
322 | * | 325 | * |
323 | * Must be called with pm_mutex held | 326 | * This routine must be called with pm_mutex held. |
324 | */ | 327 | */ |
325 | |||
326 | int hibernation_snapshot(int platform_mode) | 328 | int hibernation_snapshot(int platform_mode) |
327 | { | 329 | { |
330 | pm_message_t msg = PMSG_RECOVER; | ||
328 | int error; | 331 | int error; |
329 | gfp_t saved_mask; | ||
330 | 332 | ||
331 | error = platform_begin(platform_mode); | 333 | error = platform_begin(platform_mode); |
332 | if (error) | 334 | if (error) |
333 | goto Close; | 335 | goto Close; |
334 | 336 | ||
337 | error = dpm_prepare(PMSG_FREEZE); | ||
338 | if (error) | ||
339 | goto Complete_devices; | ||
340 | |||
335 | /* Preallocate image memory before shutting down devices. */ | 341 | /* Preallocate image memory before shutting down devices. */ |
336 | error = hibernate_preallocate_memory(); | 342 | error = hibernate_preallocate_memory(); |
337 | if (error) | 343 | if (error) |
338 | goto Close; | 344 | goto Complete_devices; |
339 | 345 | ||
340 | suspend_console(); | 346 | suspend_console(); |
341 | saved_mask = clear_gfp_allowed_mask(GFP_IOFS); | 347 | pm_restrict_gfp_mask(); |
342 | error = dpm_suspend_start(PMSG_FREEZE); | 348 | error = dpm_suspend(PMSG_FREEZE); |
343 | if (error) | 349 | if (error) |
344 | goto Recover_platform; | 350 | goto Recover_platform; |
345 | 351 | ||
@@ -347,17 +353,27 @@ int hibernation_snapshot(int platform_mode) | |||
347 | goto Recover_platform; | 353 | goto Recover_platform; |
348 | 354 | ||
349 | error = create_image(platform_mode); | 355 | error = create_image(platform_mode); |
350 | /* Control returns here after successful restore */ | 356 | /* |
357 | * Control returns here (1) after the image has been created or the | ||
358 | * image creation has failed and (2) after a successful restore. | ||
359 | */ | ||
351 | 360 | ||
352 | Resume_devices: | 361 | Resume_devices: |
353 | /* We may need to release the preallocated image pages here. */ | 362 | /* We may need to release the preallocated image pages here. */ |
354 | if (error || !in_suspend) | 363 | if (error || !in_suspend) |
355 | swsusp_free(); | 364 | swsusp_free(); |
356 | 365 | ||
357 | dpm_resume_end(in_suspend ? | 366 | msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; |
358 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); | 367 | dpm_resume(msg); |
359 | set_gfp_allowed_mask(saved_mask); | 368 | |
369 | if (error || !in_suspend) | ||
370 | pm_restore_gfp_mask(); | ||
371 | |||
360 | resume_console(); | 372 | resume_console(); |
373 | |||
374 | Complete_devices: | ||
375 | dpm_complete(msg); | ||
376 | |||
361 | Close: | 377 | Close: |
362 | platform_end(platform_mode); | 378 | platform_end(platform_mode); |
363 | return error; | 379 | return error; |
@@ -368,13 +384,14 @@ int hibernation_snapshot(int platform_mode) | |||
368 | } | 384 | } |
369 | 385 | ||
370 | /** | 386 | /** |
371 | * resume_target_kernel - prepare devices that need to be suspended with | 387 | * resume_target_kernel - Restore system state from a hibernation image. |
372 | * interrupts off, restore the contents of highmem that have not been | 388 | * @platform_mode: Whether or not to use the platform driver. |
373 | * restored yet from the image and run the low level code that will restore | 389 | * |
374 | * the remaining contents of memory and switch to the just restored target | 390 | * Execute device drivers' .freeze_noirq() callbacks, restore the contents of |
375 | * kernel. | 391 | * highmem that have not been restored yet from the image and run the low-level |
392 | * code that will restore the remaining contents of memory and switch to the | ||
393 | * just restored target kernel. | ||
376 | */ | 394 | */ |
377 | |||
378 | static int resume_target_kernel(bool platform_mode) | 395 | static int resume_target_kernel(bool platform_mode) |
379 | { | 396 | { |
380 | int error; | 397 | int error; |
@@ -396,34 +413,36 @@ static int resume_target_kernel(bool platform_mode) | |||
396 | 413 | ||
397 | local_irq_disable(); | 414 | local_irq_disable(); |
398 | 415 | ||
399 | error = sysdev_suspend(PMSG_QUIESCE); | 416 | error = syscore_suspend(); |
400 | if (error) | 417 | if (error) |
401 | goto Enable_irqs; | 418 | goto Enable_irqs; |
402 | 419 | ||
403 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | ||
404 | save_processor_state(); | 420 | save_processor_state(); |
405 | error = restore_highmem(); | 421 | error = restore_highmem(); |
406 | if (!error) { | 422 | if (!error) { |
407 | error = swsusp_arch_resume(); | 423 | error = swsusp_arch_resume(); |
408 | /* | 424 | /* |
409 | * The code below is only ever reached in case of a failure. | 425 | * The code below is only ever reached in case of a failure. |
410 | * Otherwise execution continues at place where | 426 | * Otherwise, execution continues at the place where |
411 | * swsusp_arch_suspend() was called | 427 | * swsusp_arch_suspend() was called. |
412 | */ | 428 | */ |
413 | BUG_ON(!error); | 429 | BUG_ON(!error); |
414 | /* This call to restore_highmem() undos the previous one */ | 430 | /* |
431 | * This call to restore_highmem() reverts the changes made by | ||
432 | * the previous one. | ||
433 | */ | ||
415 | restore_highmem(); | 434 | restore_highmem(); |
416 | } | 435 | } |
417 | /* | 436 | /* |
418 | * The only reason why swsusp_arch_resume() can fail is memory being | 437 | * The only reason why swsusp_arch_resume() can fail is memory being |
419 | * very tight, so we have to free it as soon as we can to avoid | 438 | * very tight, so we have to free it as soon as we can to avoid |
420 | * subsequent failures | 439 | * subsequent failures. |
421 | */ | 440 | */ |
422 | swsusp_free(); | 441 | swsusp_free(); |
423 | restore_processor_state(); | 442 | restore_processor_state(); |
424 | touch_softlockup_watchdog(); | 443 | touch_softlockup_watchdog(); |
425 | 444 | ||
426 | sysdev_resume(); | 445 | syscore_resume(); |
427 | 446 | ||
428 | Enable_irqs: | 447 | Enable_irqs: |
429 | local_irq_enable(); | 448 | local_irq_enable(); |
@@ -440,42 +459,36 @@ static int resume_target_kernel(bool platform_mode) | |||
440 | } | 459 | } |
441 | 460 | ||
442 | /** | 461 | /** |
443 | * hibernation_restore - quiesce devices and restore the hibernation | 462 | * hibernation_restore - Quiesce devices and restore from a hibernation image. |
444 | * snapshot image. If successful, control returns in hibernation_snaphot() | 463 | * @platform_mode: If set, use platform driver to prepare for the transition. |
445 | * @platform_mode - if set, use the platform driver, if available, to | ||
446 | * prepare the platform firmware for the transition. | ||
447 | * | 464 | * |
448 | * Must be called with pm_mutex held | 465 | * This routine must be called with pm_mutex held. If it is successful, control |
466 | * reappears in the restored target kernel in hibernation_snaphot(). | ||
449 | */ | 467 | */ |
450 | |||
451 | int hibernation_restore(int platform_mode) | 468 | int hibernation_restore(int platform_mode) |
452 | { | 469 | { |
453 | int error; | 470 | int error; |
454 | gfp_t saved_mask; | ||
455 | 471 | ||
456 | pm_prepare_console(); | 472 | pm_prepare_console(); |
457 | suspend_console(); | 473 | suspend_console(); |
458 | saved_mask = clear_gfp_allowed_mask(GFP_IOFS); | 474 | pm_restrict_gfp_mask(); |
459 | error = dpm_suspend_start(PMSG_QUIESCE); | 475 | error = dpm_suspend_start(PMSG_QUIESCE); |
460 | if (!error) { | 476 | if (!error) { |
461 | error = resume_target_kernel(platform_mode); | 477 | error = resume_target_kernel(platform_mode); |
462 | dpm_resume_end(PMSG_RECOVER); | 478 | dpm_resume_end(PMSG_RECOVER); |
463 | } | 479 | } |
464 | set_gfp_allowed_mask(saved_mask); | 480 | pm_restore_gfp_mask(); |
465 | resume_console(); | 481 | resume_console(); |
466 | pm_restore_console(); | 482 | pm_restore_console(); |
467 | return error; | 483 | return error; |
468 | } | 484 | } |
469 | 485 | ||
470 | /** | 486 | /** |
471 | * hibernation_platform_enter - enter the hibernation state using the | 487 | * hibernation_platform_enter - Power off the system using the platform driver. |
472 | * platform driver (if available) | ||
473 | */ | 488 | */ |
474 | |||
475 | int hibernation_platform_enter(void) | 489 | int hibernation_platform_enter(void) |
476 | { | 490 | { |
477 | int error; | 491 | int error; |
478 | gfp_t saved_mask; | ||
479 | 492 | ||
480 | if (!hibernation_ops) | 493 | if (!hibernation_ops) |
481 | return -ENOSYS; | 494 | return -ENOSYS; |
@@ -491,7 +504,6 @@ int hibernation_platform_enter(void) | |||
491 | 504 | ||
492 | entering_platform_hibernation = true; | 505 | entering_platform_hibernation = true; |
493 | suspend_console(); | 506 | suspend_console(); |
494 | saved_mask = clear_gfp_allowed_mask(GFP_IOFS); | ||
495 | error = dpm_suspend_start(PMSG_HIBERNATE); | 507 | error = dpm_suspend_start(PMSG_HIBERNATE); |
496 | if (error) { | 508 | if (error) { |
497 | if (hibernation_ops->recover) | 509 | if (hibernation_ops->recover) |
@@ -512,8 +524,8 @@ int hibernation_platform_enter(void) | |||
512 | goto Platform_finish; | 524 | goto Platform_finish; |
513 | 525 | ||
514 | local_irq_disable(); | 526 | local_irq_disable(); |
515 | sysdev_suspend(PMSG_HIBERNATE); | 527 | syscore_suspend(); |
516 | if (!pm_check_wakeup_events()) { | 528 | if (pm_wakeup_pending()) { |
517 | error = -EAGAIN; | 529 | error = -EAGAIN; |
518 | goto Power_up; | 530 | goto Power_up; |
519 | } | 531 | } |
@@ -523,7 +535,7 @@ int hibernation_platform_enter(void) | |||
523 | while (1); | 535 | while (1); |
524 | 536 | ||
525 | Power_up: | 537 | Power_up: |
526 | sysdev_resume(); | 538 | syscore_resume(); |
527 | local_irq_enable(); | 539 | local_irq_enable(); |
528 | enable_nonboot_cpus(); | 540 | enable_nonboot_cpus(); |
529 | 541 | ||
@@ -535,7 +547,6 @@ int hibernation_platform_enter(void) | |||
535 | Resume_devices: | 547 | Resume_devices: |
536 | entering_platform_hibernation = false; | 548 | entering_platform_hibernation = false; |
537 | dpm_resume_end(PMSG_RESTORE); | 549 | dpm_resume_end(PMSG_RESTORE); |
538 | set_gfp_allowed_mask(saved_mask); | ||
539 | resume_console(); | 550 | resume_console(); |
540 | 551 | ||
541 | Close: | 552 | Close: |
@@ -545,12 +556,12 @@ int hibernation_platform_enter(void) | |||
545 | } | 556 | } |
546 | 557 | ||
547 | /** | 558 | /** |
548 | * power_down - Shut the machine down for hibernation. | 559 | * power_down - Shut the machine down for hibernation. |
549 | * | 560 | * |
550 | * Use the platform driver, if configured so; otherwise try | 561 | * Use the platform driver, if configured, to put the system into the sleep |
551 | * to power off or reboot. | 562 | * state corresponding to hibernation, or try to power it off or reboot, |
563 | * depending on the value of hibernation_mode. | ||
552 | */ | 564 | */ |
553 | |||
554 | static void power_down(void) | 565 | static void power_down(void) |
555 | { | 566 | { |
556 | switch (hibernation_mode) { | 567 | switch (hibernation_mode) { |
@@ -587,9 +598,8 @@ static int prepare_processes(void) | |||
587 | } | 598 | } |
588 | 599 | ||
589 | /** | 600 | /** |
590 | * hibernate - The granpappy of the built-in hibernation management | 601 | * hibernate - Carry out system hibernation, including saving the image. |
591 | */ | 602 | */ |
592 | |||
593 | int hibernate(void) | 603 | int hibernate(void) |
594 | { | 604 | { |
595 | int error; | 605 | int error; |
@@ -638,11 +648,15 @@ int hibernate(void) | |||
638 | 648 | ||
639 | if (hibernation_mode == HIBERNATION_PLATFORM) | 649 | if (hibernation_mode == HIBERNATION_PLATFORM) |
640 | flags |= SF_PLATFORM_MODE; | 650 | flags |= SF_PLATFORM_MODE; |
651 | if (nocompress) | ||
652 | flags |= SF_NOCOMPRESS_MODE; | ||
641 | pr_debug("PM: writing image.\n"); | 653 | pr_debug("PM: writing image.\n"); |
642 | error = swsusp_write(flags); | 654 | error = swsusp_write(flags); |
643 | swsusp_free(); | 655 | swsusp_free(); |
644 | if (!error) | 656 | if (!error) |
645 | power_down(); | 657 | power_down(); |
658 | in_suspend = 0; | ||
659 | pm_restore_gfp_mask(); | ||
646 | } else { | 660 | } else { |
647 | pr_debug("PM: Image restored successfully.\n"); | 661 | pr_debug("PM: Image restored successfully.\n"); |
648 | } | 662 | } |
@@ -663,17 +677,20 @@ int hibernate(void) | |||
663 | 677 | ||
664 | 678 | ||
665 | /** | 679 | /** |
666 | * software_resume - Resume from a saved image. | 680 | * software_resume - Resume from a saved hibernation image. |
681 | * | ||
682 | * This routine is called as a late initcall, when all devices have been | ||
683 | * discovered and initialized already. | ||
667 | * | 684 | * |
668 | * Called as a late_initcall (so all devices are discovered and | 685 | * The image reading code is called to see if there is a hibernation image |
669 | * initialized), we call swsusp to see if we have a saved image or not. | 686 | * available for reading. If that is the case, devices are quiesced and the |
670 | * If so, we quiesce devices, the restore the saved image. We will | 687 | * contents of memory is restored from the saved image. |
671 | * return above (in hibernate() ) if everything goes well. | ||
672 | * Otherwise, we fail gracefully and return to the normally | ||
673 | * scheduled program. | ||
674 | * | 688 | * |
689 | * If this is successful, control reappears in the restored target kernel in | ||
690 | * hibernation_snaphot() which returns to hibernate(). Otherwise, the routine | ||
691 | * attempts to recover gracefully and make the kernel return to the normal mode | ||
692 | * of operation. | ||
675 | */ | 693 | */ |
676 | |||
677 | static int software_resume(void) | 694 | static int software_resume(void) |
678 | { | 695 | { |
679 | int error; | 696 | int error; |
@@ -705,7 +722,7 @@ static int software_resume(void) | |||
705 | goto Unlock; | 722 | goto Unlock; |
706 | } | 723 | } |
707 | 724 | ||
708 | pr_debug("PM: Checking image partition %s\n", resume_file); | 725 | pr_debug("PM: Checking hibernation image partition %s\n", resume_file); |
709 | 726 | ||
710 | /* Check if the device is there */ | 727 | /* Check if the device is there */ |
711 | swsusp_resume_device = name_to_dev_t(resume_file); | 728 | swsusp_resume_device = name_to_dev_t(resume_file); |
@@ -730,10 +747,10 @@ static int software_resume(void) | |||
730 | } | 747 | } |
731 | 748 | ||
732 | Check_image: | 749 | Check_image: |
733 | pr_debug("PM: Resume from partition %d:%d\n", | 750 | pr_debug("PM: Hibernation image partition %d:%d present\n", |
734 | MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); | 751 | MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); |
735 | 752 | ||
736 | pr_debug("PM: Checking hibernation image.\n"); | 753 | pr_debug("PM: Looking for hibernation image.\n"); |
737 | error = swsusp_check(); | 754 | error = swsusp_check(); |
738 | if (error) | 755 | if (error) |
739 | goto Unlock; | 756 | goto Unlock; |
@@ -765,14 +782,14 @@ static int software_resume(void) | |||
765 | goto Done; | 782 | goto Done; |
766 | } | 783 | } |
767 | 784 | ||
768 | pr_debug("PM: Reading hibernation image.\n"); | 785 | pr_debug("PM: Loading hibernation image.\n"); |
769 | 786 | ||
770 | error = swsusp_read(&flags); | 787 | error = swsusp_read(&flags); |
771 | swsusp_close(FMODE_READ); | 788 | swsusp_close(FMODE_READ); |
772 | if (!error) | 789 | if (!error) |
773 | hibernation_restore(flags & SF_PLATFORM_MODE); | 790 | hibernation_restore(flags & SF_PLATFORM_MODE); |
774 | 791 | ||
775 | printk(KERN_ERR "PM: Restore failed, recovering.\n"); | 792 | printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n"); |
776 | swsusp_free(); | 793 | swsusp_free(); |
777 | thaw_processes(); | 794 | thaw_processes(); |
778 | Done: | 795 | Done: |
@@ -785,7 +802,7 @@ static int software_resume(void) | |||
785 | /* For success case, the suspend path will release the lock */ | 802 | /* For success case, the suspend path will release the lock */ |
786 | Unlock: | 803 | Unlock: |
787 | mutex_unlock(&pm_mutex); | 804 | mutex_unlock(&pm_mutex); |
788 | pr_debug("PM: Resume from disk failed.\n"); | 805 | pr_debug("PM: Hibernation image not present or could not be loaded.\n"); |
789 | return error; | 806 | return error; |
790 | close_finish: | 807 | close_finish: |
791 | swsusp_close(FMODE_READ); | 808 | swsusp_close(FMODE_READ); |
@@ -803,21 +820,17 @@ static const char * const hibernation_modes[] = { | |||
803 | [HIBERNATION_TESTPROC] = "testproc", | 820 | [HIBERNATION_TESTPROC] = "testproc", |
804 | }; | 821 | }; |
805 | 822 | ||
806 | /** | 823 | /* |
807 | * disk - Control hibernation mode | 824 | * /sys/power/disk - Control hibernation mode. |
808 | * | ||
809 | * Suspend-to-disk can be handled in several ways. We have a few options | ||
810 | * for putting the system to sleep - using the platform driver (e.g. ACPI | ||
811 | * or other hibernation_ops), powering off the system or rebooting the | ||
812 | * system (for testing) as well as the two test modes. | ||
813 | * | 825 | * |
814 | * The system can support 'platform', and that is known a priori (and | 826 | * Hibernation can be handled in several ways. There are a few different ways |
815 | * encoded by the presence of hibernation_ops). However, the user may | 827 | * to put the system into the sleep state: using the platform driver (e.g. ACPI |
816 | * choose 'shutdown' or 'reboot' as alternatives, as well as one fo the | 828 | * or other hibernation_ops), powering it off or rebooting it (for testing |
817 | * test modes, 'test' or 'testproc'. | 829 | * mostly), or using one of the two available test modes. |
818 | * | 830 | * |
819 | * show() will display what the mode is currently set to. | 831 | * The sysfs file /sys/power/disk provides an interface for selecting the |
820 | * store() will accept one of | 832 | * hibernation mode to use. Reading from this file causes the available modes |
833 | * to be printed. There are 5 modes that can be supported: | ||
821 | * | 834 | * |
822 | * 'platform' | 835 | * 'platform' |
823 | * 'shutdown' | 836 | * 'shutdown' |
@@ -825,8 +838,14 @@ static const char * const hibernation_modes[] = { | |||
825 | * 'test' | 838 | * 'test' |
826 | * 'testproc' | 839 | * 'testproc' |
827 | * | 840 | * |
828 | * It will only change to 'platform' if the system | 841 | * If a platform hibernation driver is in use, 'platform' will be supported |
829 | * supports it (as determined by having hibernation_ops). | 842 | * and will be used by default. Otherwise, 'shutdown' will be used by default. |
843 | * The selected option (i.e. the one corresponding to the current value of | ||
844 | * hibernation_mode) is enclosed by a square bracket. | ||
845 | * | ||
846 | * To select a given hibernation mode it is necessary to write the mode's | ||
847 | * string representation (as returned by reading from /sys/power/disk) back | ||
848 | * into /sys/power/disk. | ||
830 | */ | 849 | */ |
831 | 850 | ||
832 | static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, | 851 | static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, |
@@ -859,7 +878,6 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
859 | return buf-start; | 878 | return buf-start; |
860 | } | 879 | } |
861 | 880 | ||
862 | |||
863 | static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, | 881 | static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, |
864 | const char *buf, size_t n) | 882 | const char *buf, size_t n) |
865 | { | 883 | { |
@@ -961,10 +979,33 @@ static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *att | |||
961 | 979 | ||
962 | power_attr(image_size); | 980 | power_attr(image_size); |
963 | 981 | ||
982 | static ssize_t reserved_size_show(struct kobject *kobj, | ||
983 | struct kobj_attribute *attr, char *buf) | ||
984 | { | ||
985 | return sprintf(buf, "%lu\n", reserved_size); | ||
986 | } | ||
987 | |||
988 | static ssize_t reserved_size_store(struct kobject *kobj, | ||
989 | struct kobj_attribute *attr, | ||
990 | const char *buf, size_t n) | ||
991 | { | ||
992 | unsigned long size; | ||
993 | |||
994 | if (sscanf(buf, "%lu", &size) == 1) { | ||
995 | reserved_size = size; | ||
996 | return n; | ||
997 | } | ||
998 | |||
999 | return -EINVAL; | ||
1000 | } | ||
1001 | |||
1002 | power_attr(reserved_size); | ||
1003 | |||
964 | static struct attribute * g[] = { | 1004 | static struct attribute * g[] = { |
965 | &disk_attr.attr, | 1005 | &disk_attr.attr, |
966 | &resume_attr.attr, | 1006 | &resume_attr.attr, |
967 | &image_size_attr.attr, | 1007 | &image_size_attr.attr, |
1008 | &reserved_size_attr.attr, | ||
968 | NULL, | 1009 | NULL, |
969 | }; | 1010 | }; |
970 | 1011 | ||
@@ -1004,6 +1045,15 @@ static int __init resume_offset_setup(char *str) | |||
1004 | return 1; | 1045 | return 1; |
1005 | } | 1046 | } |
1006 | 1047 | ||
1048 | static int __init hibernate_setup(char *str) | ||
1049 | { | ||
1050 | if (!strncmp(str, "noresume", 8)) | ||
1051 | noresume = 1; | ||
1052 | else if (!strncmp(str, "nocompress", 10)) | ||
1053 | nocompress = 1; | ||
1054 | return 1; | ||
1055 | } | ||
1056 | |||
1007 | static int __init noresume_setup(char *str) | 1057 | static int __init noresume_setup(char *str) |
1008 | { | 1058 | { |
1009 | noresume = 1; | 1059 | noresume = 1; |
@@ -1013,3 +1063,4 @@ static int __init noresume_setup(char *str) | |||
1013 | __setup("noresume", noresume_setup); | 1063 | __setup("noresume", noresume_setup); |
1014 | __setup("resume_offset=", resume_offset_setup); | 1064 | __setup("resume_offset=", resume_offset_setup); |
1015 | __setup("resume=", resume_setup); | 1065 | __setup("resume=", resume_setup); |
1066 | __setup("hibernate=", hibernate_setup); | ||