diff options
Diffstat (limited to 'kernel/power/main.c')
-rw-r--r-- | kernel/power/main.c | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c index c9632f841f64..f99ed6a75eac 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -287,17 +287,38 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) | |||
287 | */ | 287 | */ |
288 | static int suspend_enter(suspend_state_t state) | 288 | static int suspend_enter(suspend_state_t state) |
289 | { | 289 | { |
290 | int error = 0; | 290 | int error; |
291 | 291 | ||
292 | device_pm_lock(); | 292 | device_pm_lock(); |
293 | arch_suspend_disable_irqs(); | ||
294 | BUG_ON(!irqs_disabled()); | ||
295 | 293 | ||
296 | if ((error = device_power_down(PMSG_SUSPEND))) { | 294 | if (suspend_ops->prepare) { |
295 | error = suspend_ops->prepare(); | ||
296 | if (error) | ||
297 | goto Done; | ||
298 | } | ||
299 | |||
300 | error = device_power_down(PMSG_SUSPEND); | ||
301 | if (error) { | ||
297 | printk(KERN_ERR "PM: Some devices failed to power down\n"); | 302 | printk(KERN_ERR "PM: Some devices failed to power down\n"); |
298 | goto Done; | 303 | goto Platfrom_finish; |
304 | } | ||
305 | |||
306 | if (suspend_ops->prepare_late) { | ||
307 | error = suspend_ops->prepare_late(); | ||
308 | if (error) | ||
309 | goto Power_up_devices; | ||
299 | } | 310 | } |
300 | 311 | ||
312 | if (suspend_test(TEST_PLATFORM)) | ||
313 | goto Platform_wake; | ||
314 | |||
315 | error = disable_nonboot_cpus(); | ||
316 | if (error || suspend_test(TEST_CPUS)) | ||
317 | goto Enable_cpus; | ||
318 | |||
319 | arch_suspend_disable_irqs(); | ||
320 | BUG_ON(!irqs_disabled()); | ||
321 | |||
301 | error = sysdev_suspend(PMSG_SUSPEND); | 322 | error = sysdev_suspend(PMSG_SUSPEND); |
302 | if (!error) { | 323 | if (!error) { |
303 | if (!suspend_test(TEST_CORE)) | 324 | if (!suspend_test(TEST_CORE)) |
@@ -305,11 +326,26 @@ static int suspend_enter(suspend_state_t state) | |||
305 | sysdev_resume(); | 326 | sysdev_resume(); |
306 | } | 327 | } |
307 | 328 | ||
308 | device_power_up(PMSG_RESUME); | ||
309 | Done: | ||
310 | arch_suspend_enable_irqs(); | 329 | arch_suspend_enable_irqs(); |
311 | BUG_ON(irqs_disabled()); | 330 | BUG_ON(irqs_disabled()); |
331 | |||
332 | Enable_cpus: | ||
333 | enable_nonboot_cpus(); | ||
334 | |||
335 | Platform_wake: | ||
336 | if (suspend_ops->wake) | ||
337 | suspend_ops->wake(); | ||
338 | |||
339 | Power_up_devices: | ||
340 | device_power_up(PMSG_RESUME); | ||
341 | |||
342 | Platfrom_finish: | ||
343 | if (suspend_ops->finish) | ||
344 | suspend_ops->finish(); | ||
345 | |||
346 | Done: | ||
312 | device_pm_unlock(); | 347 | device_pm_unlock(); |
348 | |||
313 | return error; | 349 | return error; |
314 | } | 350 | } |
315 | 351 | ||
@@ -341,23 +377,8 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
341 | if (suspend_test(TEST_DEVICES)) | 377 | if (suspend_test(TEST_DEVICES)) |
342 | goto Recover_platform; | 378 | goto Recover_platform; |
343 | 379 | ||
344 | if (suspend_ops->prepare) { | 380 | suspend_enter(state); |
345 | error = suspend_ops->prepare(); | ||
346 | if (error) | ||
347 | goto Resume_devices; | ||
348 | } | ||
349 | |||
350 | if (suspend_test(TEST_PLATFORM)) | ||
351 | goto Finish; | ||
352 | 381 | ||
353 | error = disable_nonboot_cpus(); | ||
354 | if (!error && !suspend_test(TEST_CPUS)) | ||
355 | suspend_enter(state); | ||
356 | |||
357 | enable_nonboot_cpus(); | ||
358 | Finish: | ||
359 | if (suspend_ops->finish) | ||
360 | suspend_ops->finish(); | ||
361 | Resume_devices: | 382 | Resume_devices: |
362 | suspend_test_start(); | 383 | suspend_test_start(); |
363 | device_resume(PMSG_RESUME); | 384 | device_resume(PMSG_RESUME); |