Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 139002
b: refs/heads/master
c: 4aecd67
h: refs/heads/master
v: v3
  • Loading branch information
Rafael J. Wysocki committed Mar 30, 2009
1 parent b67ce37 commit c25116b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 900af0d973856d6feb6fc088c2d0d3fde57707d3
refs/heads/master: 4aecd6718939eb3c4145b248369b65f7483a8a02
109 changes: 61 additions & 48 deletions trunk/kernel/power/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,22 @@ static int create_image(int platform_mode)
goto Unlock;
}

error = platform_pre_snapshot(platform_mode);
if (error || hibernation_test(TEST_PLATFORM))
goto Platform_finish;

error = disable_nonboot_cpus();
if (error || hibernation_test(TEST_CPUS)
|| hibernation_testmode(HIBERNATION_TEST))
goto Enable_cpus;

local_irq_disable();

sysdev_suspend(PMSG_FREEZE);
if (error) {
printk(KERN_ERR "PM: Some devices failed to power down, "
"aborting hibernation\n");
goto Power_up_devices;
goto Enable_irqs;
}

if (hibernation_test(TEST_CORE))
Expand All @@ -250,15 +259,22 @@ static int create_image(int platform_mode)
restore_processor_state();
if (!in_suspend)
platform_leave(platform_mode);

Power_up:
sysdev_resume();
/* NOTE: device_power_up() is just a resume() for devices
* that suspended with irqs off ... no overall powerup.
*/

Power_up_devices:
Enable_irqs:
local_irq_enable();

Enable_cpus:
enable_nonboot_cpus();

Platform_finish:
platform_finish(platform_mode);

device_power_up(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);

Expand Down Expand Up @@ -298,25 +314,9 @@ int hibernation_snapshot(int platform_mode)
if (hibernation_test(TEST_DEVICES))
goto Recover_platform;

error = platform_pre_snapshot(platform_mode);
if (error || hibernation_test(TEST_PLATFORM))
goto Finish;

error = disable_nonboot_cpus();
if (!error) {
if (hibernation_test(TEST_CPUS))
goto Enable_cpus;

if (hibernation_testmode(HIBERNATION_TEST))
goto Enable_cpus;
error = create_image(platform_mode);
/* Control returns here after successful restore */

error = create_image(platform_mode);
/* Control returns here after successful restore */
}
Enable_cpus:
enable_nonboot_cpus();
Finish:
platform_finish(platform_mode);
Resume_devices:
device_resume(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
Expand All @@ -338,7 +338,7 @@ int hibernation_snapshot(int platform_mode)
* kernel.
*/

static int resume_target_kernel(void)
static int resume_target_kernel(bool platform_mode)
{
int error;

Expand All @@ -351,9 +351,20 @@ static int resume_target_kernel(void)
goto Unlock;
}

error = platform_pre_restore(platform_mode);
if (error)
goto Cleanup;

error = disable_nonboot_cpus();
if (error)
goto Enable_cpus;

local_irq_disable();

sysdev_suspend(PMSG_QUIESCE);
error = sysdev_suspend(PMSG_QUIESCE);
if (error)
goto Enable_irqs;

/* We'll ignore saved state, but this gets preempt count (etc) right */
save_processor_state();
error = restore_highmem();
Expand All @@ -379,8 +390,15 @@ static int resume_target_kernel(void)

sysdev_resume();

Enable_irqs:
local_irq_enable();

Enable_cpus:
enable_nonboot_cpus();

Cleanup:
platform_restore_cleanup(platform_mode);

device_power_up(PMSG_RECOVER);

Unlock:
Expand All @@ -405,19 +423,10 @@ int hibernation_restore(int platform_mode)
pm_prepare_console();
suspend_console();
error = device_suspend(PMSG_QUIESCE);
if (error)
goto Finish;

error = platform_pre_restore(platform_mode);
if (!error) {
error = disable_nonboot_cpus();
if (!error)
error = resume_target_kernel();
enable_nonboot_cpus();
error = resume_target_kernel(platform_mode);
device_resume(PMSG_RECOVER);
}
platform_restore_cleanup(platform_mode);
device_resume(PMSG_RECOVER);
Finish:
resume_console();
pm_restore_console();
return error;
Expand Down Expand Up @@ -453,34 +462,38 @@ int hibernation_platform_enter(void)
goto Resume_devices;
}

device_pm_lock();

error = device_power_down(PMSG_HIBERNATE);
if (error)
goto Unlock;

error = hibernation_ops->prepare();
if (error)
goto Resume_devices;
goto Platofrm_finish;

error = disable_nonboot_cpus();
if (error)
goto Finish;

device_pm_lock();

error = device_power_down(PMSG_HIBERNATE);
if (!error) {
local_irq_disable();
sysdev_suspend(PMSG_HIBERNATE);
hibernation_ops->enter();
/* We should never get here */
while (1);
}
goto Platofrm_finish;

device_pm_unlock();
local_irq_disable();
sysdev_suspend(PMSG_HIBERNATE);
hibernation_ops->enter();
/* We should never get here */
while (1);

/*
* We don't need to reenable the nonboot CPUs or resume consoles, since
* the system is going to be halted anyway.
*/
Finish:
Platofrm_finish:
hibernation_ops->finish();

device_power_up(PMSG_RESTORE);

Unlock:
device_pm_unlock();

Resume_devices:
entering_platform_hibernation = false;
device_resume(PMSG_RESTORE);
Expand Down

0 comments on commit c25116b

Please sign in to comment.