diff options
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r-- | kernel/power/disk.c | 63 |
1 files changed, 46 insertions, 17 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index e50f4da18fd5..8b15f777010a 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -278,21 +278,50 @@ int hibernation_platform_enter(void) | |||
278 | { | 278 | { |
279 | int error; | 279 | int error; |
280 | 280 | ||
281 | if (hibernation_ops) { | 281 | if (!hibernation_ops) |
282 | kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); | 282 | return -ENOSYS; |
283 | /* | 283 | |
284 | * We have cancelled the power transition by running | 284 | /* |
285 | * hibernation_ops->finish() before saving the image, so we | 285 | * We have cancelled the power transition by running |
286 | * should let the firmware know that we're going to enter the | 286 | * hibernation_ops->finish() before saving the image, so we should let |
287 | * sleep state after all | 287 | * the firmware know that we're going to enter the sleep state after all |
288 | */ | 288 | */ |
289 | error = hibernation_ops->prepare(); | 289 | error = hibernation_ops->start(); |
290 | sysdev_shutdown(); | 290 | if (error) |
291 | if (!error) | 291 | return error; |
292 | error = hibernation_ops->enter(); | 292 | |
293 | } else { | 293 | suspend_console(); |
294 | error = -ENOSYS; | 294 | error = device_suspend(PMSG_SUSPEND); |
295 | if (error) | ||
296 | goto Resume_console; | ||
297 | |||
298 | error = hibernation_ops->prepare(); | ||
299 | if (error) | ||
300 | goto Resume_devices; | ||
301 | |||
302 | error = disable_nonboot_cpus(); | ||
303 | if (error) | ||
304 | goto Finish; | ||
305 | |||
306 | local_irq_disable(); | ||
307 | error = device_power_down(PMSG_SUSPEND); | ||
308 | if (!error) { | ||
309 | hibernation_ops->enter(); | ||
310 | /* We should never get here */ | ||
311 | while (1); | ||
295 | } | 312 | } |
313 | local_irq_enable(); | ||
314 | |||
315 | /* | ||
316 | * We don't need to reenable the nonboot CPUs or resume consoles, since | ||
317 | * the system is going to be halted anyway. | ||
318 | */ | ||
319 | Finish: | ||
320 | hibernation_ops->finish(); | ||
321 | Resume_devices: | ||
322 | device_resume(); | ||
323 | Resume_console: | ||
324 | resume_console(); | ||
296 | return error; | 325 | return error; |
297 | } | 326 | } |
298 | 327 | ||
@@ -309,14 +338,14 @@ static void power_down(void) | |||
309 | case HIBERNATION_TEST: | 338 | case HIBERNATION_TEST: |
310 | case HIBERNATION_TESTPROC: | 339 | case HIBERNATION_TESTPROC: |
311 | break; | 340 | break; |
312 | case HIBERNATION_SHUTDOWN: | ||
313 | kernel_power_off(); | ||
314 | break; | ||
315 | case HIBERNATION_REBOOT: | 341 | case HIBERNATION_REBOOT: |
316 | kernel_restart(NULL); | 342 | kernel_restart(NULL); |
317 | break; | 343 | break; |
318 | case HIBERNATION_PLATFORM: | 344 | case HIBERNATION_PLATFORM: |
319 | hibernation_platform_enter(); | 345 | hibernation_platform_enter(); |
346 | case HIBERNATION_SHUTDOWN: | ||
347 | kernel_power_off(); | ||
348 | break; | ||
320 | } | 349 | } |
321 | kernel_halt(); | 350 | kernel_halt(); |
322 | /* | 351 | /* |