aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c331
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
32static int nocompress = 0;
32static int noresume = 0; 33static int noresume = 0;
33static char resume_file[256] = CONFIG_PM_STD_PARTITION; 34static char resume_file[256] = CONFIG_PM_STD_PARTITION;
34dev_t swsusp_resume_device; 35dev_t swsusp_resume_device;
@@ -50,18 +51,17 @@ enum {
50 51
51static int hibernation_mode = HIBERNATION_SHUTDOWN; 52static int hibernation_mode = HIBERNATION_SHUTDOWN;
52 53
53static struct platform_hibernation_ops *hibernation_ops; 54static 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 60void hibernation_set_ops(const struct platform_hibernation_ops *ops)
60void 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
120static int platform_begin(int platform_mode) 119static 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
131static void platform_end(int platform_mode) 129static 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
142static int platform_pre_snapshot(int platform_mode) 143static 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
153static void platform_leave(int platform_mode) 158static 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
164static void platform_finish(int platform_mode) 173static 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
176static int platform_pre_restore(int platform_mode) 189static 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
189static void platform_restore_cleanup(int platform_mode) 206static 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
200static void platform_recover(int platform_mode) 216static 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
214void swsusp_show_speed(struct timeval *start, struct timeval *stop, 229void 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
241static int create_image(int platform_mode) 259static 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
326int hibernation_snapshot(int platform_mode) 328int 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
378static int resume_target_kernel(bool platform_mode) 395static 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
451int hibernation_restore(int platform_mode) 468int 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
475int hibernation_platform_enter(void) 489int 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
554static void power_down(void) 565static 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
593int hibernate(void) 603int 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
677static int software_resume(void) 694static 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;
790close_finish: 807close_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
832static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, 851static 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
863static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, 881static 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
962power_attr(image_size); 980power_attr(image_size);
963 981
982static 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
988static 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
1002power_attr(reserved_size);
1003
964static struct attribute * g[] = { 1004static 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
1048static 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
1007static int __init noresume_setup(char *str) 1057static 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);