aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:20:30 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-12-30 00:21:47 -0500
commitd392da5207352f09030e95d9ea335a4225667ec0 (patch)
tree7d6cd1932afcad0a5619a5c504a6d93ca318187c /kernel/power/hibernate.c
parente39d5ef678045d61812c1401f04fe8edb14d6359 (diff)
parent387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff)
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index c77963938bca..048d0b514831 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -29,6 +29,7 @@
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;
@@ -326,7 +327,6 @@ static int create_image(int platform_mode)
326int hibernation_snapshot(int platform_mode) 327int hibernation_snapshot(int platform_mode)
327{ 328{
328 int error; 329 int error;
329 gfp_t saved_mask;
330 330
331 error = platform_begin(platform_mode); 331 error = platform_begin(platform_mode);
332 if (error) 332 if (error)
@@ -338,8 +338,7 @@ int hibernation_snapshot(int platform_mode)
338 goto Close; 338 goto Close;
339 339
340 suspend_console(); 340 suspend_console();
341 hibernation_freeze_swap(); 341 pm_restrict_gfp_mask();
342 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
343 error = dpm_suspend_start(PMSG_FREEZE); 342 error = dpm_suspend_start(PMSG_FREEZE);
344 if (error) 343 if (error)
345 goto Recover_platform; 344 goto Recover_platform;
@@ -348,7 +347,10 @@ int hibernation_snapshot(int platform_mode)
348 goto Recover_platform; 347 goto Recover_platform;
349 348
350 error = create_image(platform_mode); 349 error = create_image(platform_mode);
351 /* Control returns here after successful restore */ 350 /*
351 * Control returns here (1) after the image has been created or the
352 * image creation has failed and (2) after a successful restore.
353 */
352 354
353 Resume_devices: 355 Resume_devices:
354 /* We may need to release the preallocated image pages here. */ 356 /* We may need to release the preallocated image pages here. */
@@ -357,7 +359,10 @@ int hibernation_snapshot(int platform_mode)
357 359
358 dpm_resume_end(in_suspend ? 360 dpm_resume_end(in_suspend ?
359 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 361 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
360 set_gfp_allowed_mask(saved_mask); 362
363 if (error || !in_suspend)
364 pm_restore_gfp_mask();
365
361 resume_console(); 366 resume_console();
362 Close: 367 Close:
363 platform_end(platform_mode); 368 platform_end(platform_mode);
@@ -452,17 +457,16 @@ static int resume_target_kernel(bool platform_mode)
452int hibernation_restore(int platform_mode) 457int hibernation_restore(int platform_mode)
453{ 458{
454 int error; 459 int error;
455 gfp_t saved_mask;
456 460
457 pm_prepare_console(); 461 pm_prepare_console();
458 suspend_console(); 462 suspend_console();
459 saved_mask = clear_gfp_allowed_mask(GFP_IOFS); 463 pm_restrict_gfp_mask();
460 error = dpm_suspend_start(PMSG_QUIESCE); 464 error = dpm_suspend_start(PMSG_QUIESCE);
461 if (!error) { 465 if (!error) {
462 error = resume_target_kernel(platform_mode); 466 error = resume_target_kernel(platform_mode);
463 dpm_resume_end(PMSG_RECOVER); 467 dpm_resume_end(PMSG_RECOVER);
464 } 468 }
465 set_gfp_allowed_mask(saved_mask); 469 pm_restore_gfp_mask();
466 resume_console(); 470 resume_console();
467 pm_restore_console(); 471 pm_restore_console();
468 return error; 472 return error;
@@ -476,7 +480,6 @@ int hibernation_restore(int platform_mode)
476int hibernation_platform_enter(void) 480int hibernation_platform_enter(void)
477{ 481{
478 int error; 482 int error;
479 gfp_t saved_mask;
480 483
481 if (!hibernation_ops) 484 if (!hibernation_ops)
482 return -ENOSYS; 485 return -ENOSYS;
@@ -492,7 +495,6 @@ int hibernation_platform_enter(void)
492 495
493 entering_platform_hibernation = true; 496 entering_platform_hibernation = true;
494 suspend_console(); 497 suspend_console();
495 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
496 error = dpm_suspend_start(PMSG_HIBERNATE); 498 error = dpm_suspend_start(PMSG_HIBERNATE);
497 if (error) { 499 if (error) {
498 if (hibernation_ops->recover) 500 if (hibernation_ops->recover)
@@ -536,7 +538,6 @@ int hibernation_platform_enter(void)
536 Resume_devices: 538 Resume_devices:
537 entering_platform_hibernation = false; 539 entering_platform_hibernation = false;
538 dpm_resume_end(PMSG_RESTORE); 540 dpm_resume_end(PMSG_RESTORE);
539 set_gfp_allowed_mask(saved_mask);
540 resume_console(); 541 resume_console();
541 542
542 Close: 543 Close:
@@ -639,11 +640,14 @@ int hibernate(void)
639 640
640 if (hibernation_mode == HIBERNATION_PLATFORM) 641 if (hibernation_mode == HIBERNATION_PLATFORM)
641 flags |= SF_PLATFORM_MODE; 642 flags |= SF_PLATFORM_MODE;
643 if (nocompress)
644 flags |= SF_NOCOMPRESS_MODE;
642 pr_debug("PM: writing image.\n"); 645 pr_debug("PM: writing image.\n");
643 error = swsusp_write(flags); 646 error = swsusp_write(flags);
644 swsusp_free(); 647 swsusp_free();
645 if (!error) 648 if (!error)
646 power_down(); 649 power_down();
650 pm_restore_gfp_mask();
647 } else { 651 } else {
648 pr_debug("PM: Image restored successfully.\n"); 652 pr_debug("PM: Image restored successfully.\n");
649 } 653 }
@@ -706,7 +710,7 @@ static int software_resume(void)
706 goto Unlock; 710 goto Unlock;
707 } 711 }
708 712
709 pr_debug("PM: Checking image partition %s\n", resume_file); 713 pr_debug("PM: Checking hibernation image partition %s\n", resume_file);
710 714
711 /* Check if the device is there */ 715 /* Check if the device is there */
712 swsusp_resume_device = name_to_dev_t(resume_file); 716 swsusp_resume_device = name_to_dev_t(resume_file);
@@ -731,10 +735,10 @@ static int software_resume(void)
731 } 735 }
732 736
733 Check_image: 737 Check_image:
734 pr_debug("PM: Resume from partition %d:%d\n", 738 pr_debug("PM: Hibernation image partition %d:%d present\n",
735 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); 739 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
736 740
737 pr_debug("PM: Checking hibernation image.\n"); 741 pr_debug("PM: Looking for hibernation image.\n");
738 error = swsusp_check(); 742 error = swsusp_check();
739 if (error) 743 if (error)
740 goto Unlock; 744 goto Unlock;
@@ -766,14 +770,14 @@ static int software_resume(void)
766 goto Done; 770 goto Done;
767 } 771 }
768 772
769 pr_debug("PM: Reading hibernation image.\n"); 773 pr_debug("PM: Loading hibernation image.\n");
770 774
771 error = swsusp_read(&flags); 775 error = swsusp_read(&flags);
772 swsusp_close(FMODE_READ); 776 swsusp_close(FMODE_READ);
773 if (!error) 777 if (!error)
774 hibernation_restore(flags & SF_PLATFORM_MODE); 778 hibernation_restore(flags & SF_PLATFORM_MODE);
775 779
776 printk(KERN_ERR "PM: Restore failed, recovering.\n"); 780 printk(KERN_ERR "PM: Failed to load hibernation image, recovering.\n");
777 swsusp_free(); 781 swsusp_free();
778 thaw_processes(); 782 thaw_processes();
779 Done: 783 Done:
@@ -786,7 +790,7 @@ static int software_resume(void)
786 /* For success case, the suspend path will release the lock */ 790 /* For success case, the suspend path will release the lock */
787 Unlock: 791 Unlock:
788 mutex_unlock(&pm_mutex); 792 mutex_unlock(&pm_mutex);
789 pr_debug("PM: Resume from disk failed.\n"); 793 pr_debug("PM: Hibernation image not present or could not be loaded.\n");
790 return error; 794 return error;
791close_finish: 795close_finish:
792 swsusp_close(FMODE_READ); 796 swsusp_close(FMODE_READ);
@@ -1005,6 +1009,15 @@ static int __init resume_offset_setup(char *str)
1005 return 1; 1009 return 1;
1006} 1010}
1007 1011
1012static int __init hibernate_setup(char *str)
1013{
1014 if (!strncmp(str, "noresume", 8))
1015 noresume = 1;
1016 else if (!strncmp(str, "nocompress", 10))
1017 nocompress = 1;
1018 return 1;
1019}
1020
1008static int __init noresume_setup(char *str) 1021static int __init noresume_setup(char *str)
1009{ 1022{
1010 noresume = 1; 1023 noresume = 1;
@@ -1014,3 +1027,4 @@ static int __init noresume_setup(char *str)
1014__setup("noresume", noresume_setup); 1027__setup("noresume", noresume_setup);
1015__setup("resume_offset=", resume_offset_setup); 1028__setup("resume_offset=", resume_offset_setup);
1016__setup("resume=", resume_setup); 1029__setup("resume=", resume_setup);
1030__setup("hibernate=", hibernate_setup);