diff options
Diffstat (limited to 'kernel/power/hibernate.c')
| -rw-r--r-- | kernel/power/hibernate.c | 47 | 
1 files changed, 25 insertions, 22 deletions
| diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 6d6d2887033..0a186cfde78 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -245,8 +245,8 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop,   * create_image - Create a hibernation image.   * @platform_mode: Whether or not to use the platform driver.   * - * Execute device drivers' .freeze_noirq() callbacks, create a hibernation image - * and execute the drivers' .thaw_noirq() callbacks. + * Execute device drivers' "late" and "noirq" freeze callbacks, create a + * hibernation image and run the drivers' "noirq" and "early" thaw callbacks.   *   * Control reappears in this routine after the subsequent restore.   */ @@ -254,7 +254,7 @@ static int create_image(int platform_mode)  {  	int error; -	error = dpm_suspend_noirq(PMSG_FREEZE); +	error = dpm_suspend_end(PMSG_FREEZE);  	if (error) {  		printk(KERN_ERR "PM: Some devices failed to power down, "  			"aborting hibernation\n"); @@ -306,7 +306,7 @@ static int create_image(int platform_mode)   Platform_finish:  	platform_finish(platform_mode); -	dpm_resume_noirq(in_suspend ? +	dpm_resume_start(in_suspend ?  		(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);  	return error; @@ -343,13 +343,13 @@ int hibernation_snapshot(int platform_mode)  		 * successful freezer test.  		 */  		freezer_test_done = true; -		goto Cleanup; +		goto Thaw;  	}  	error = dpm_prepare(PMSG_FREEZE);  	if (error) {  		dpm_complete(PMSG_RECOVER); -		goto Cleanup; +		goto Thaw;  	}  	suspend_console(); @@ -385,6 +385,8 @@ int hibernation_snapshot(int platform_mode)  	platform_end(platform_mode);  	return error; + Thaw: +	thaw_kernel_threads();   Cleanup:  	swsusp_free();  	goto Close; @@ -394,16 +396,16 @@ int hibernation_snapshot(int platform_mode)   * resume_target_kernel - Restore system state from a hibernation image.   * @platform_mode: Whether or not to use the platform driver.   * - * Execute device drivers' .freeze_noirq() callbacks, restore the contents of - * highmem that have not been restored yet from the image and run the low-level - * code that will restore the remaining contents of memory and switch to the - * just restored target kernel. + * Execute device drivers' "noirq" and "late" freeze callbacks, restore the + * contents of highmem that have not been restored yet from the image and run + * the low-level code that will restore the remaining contents of memory and + * switch to the just restored target kernel.   */  static int resume_target_kernel(bool platform_mode)  {  	int error; -	error = dpm_suspend_noirq(PMSG_QUIESCE); +	error = dpm_suspend_end(PMSG_QUIESCE);  	if (error) {  		printk(KERN_ERR "PM: Some devices failed to power down, "  			"aborting resume\n"); @@ -460,7 +462,7 @@ static int resume_target_kernel(bool platform_mode)   Cleanup:  	platform_restore_cleanup(platform_mode); -	dpm_resume_noirq(PMSG_RECOVER); +	dpm_resume_start(PMSG_RECOVER);  	return error;  } @@ -518,7 +520,7 @@ int hibernation_platform_enter(void)  		goto Resume_devices;  	} -	error = dpm_suspend_noirq(PMSG_HIBERNATE); +	error = dpm_suspend_end(PMSG_HIBERNATE);  	if (error)  		goto Resume_devices; @@ -549,7 +551,7 @@ int hibernation_platform_enter(void)   Platform_finish:  	hibernation_ops->finish(); -	dpm_resume_noirq(PMSG_RESTORE); +	dpm_resume_start(PMSG_RESTORE);   Resume_devices:  	entering_platform_hibernation = false; @@ -616,7 +618,7 @@ int hibernate(void)  	/* Allocate memory management structures */  	error = create_basic_memory_bitmaps();  	if (error) -		goto Exit; +		goto Enable_umh;  	printk(KERN_INFO "PM: Syncing filesystems ... ");  	sys_sync(); @@ -624,15 +626,11 @@ int hibernate(void)  	error = freeze_processes();  	if (error) -		goto Finish; +		goto Free_bitmaps;  	error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); -	if (error) -		goto Thaw; -	if (freezer_test_done) { -		freezer_test_done = false; +	if (error || freezer_test_done)  		goto Thaw; -	}  	if (in_suspend) {  		unsigned int flags = 0; @@ -657,8 +655,13 @@ int hibernate(void)   Thaw:  	thaw_processes(); - Finish: + +	/* Don't bother checking whether freezer_test_done is true */ +	freezer_test_done = false; + + Free_bitmaps:  	free_basic_memory_bitmaps(); + Enable_umh:  	usermodehelper_enable();   Exit:  	pm_notifier_call_chain(PM_POST_HIBERNATION); | 
