diff options
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r-- | kernel/power/disk.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 4a4a206b1979..320bb0949bdf 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -214,7 +214,7 @@ static int create_image(int platform_mode) | |||
214 | return error; | 214 | return error; |
215 | 215 | ||
216 | device_pm_lock(); | 216 | device_pm_lock(); |
217 | local_irq_disable(); | 217 | |
218 | /* At this point, device_suspend() has been called, but *not* | 218 | /* At this point, device_suspend() has been called, but *not* |
219 | * device_power_down(). We *must* call device_power_down() now. | 219 | * device_power_down(). We *must* call device_power_down() now. |
220 | * Otherwise, drivers for some devices (e.g. interrupt controllers) | 220 | * Otherwise, drivers for some devices (e.g. interrupt controllers) |
@@ -225,8 +225,11 @@ static int create_image(int platform_mode) | |||
225 | if (error) { | 225 | if (error) { |
226 | printk(KERN_ERR "PM: Some devices failed to power down, " | 226 | printk(KERN_ERR "PM: Some devices failed to power down, " |
227 | "aborting hibernation\n"); | 227 | "aborting hibernation\n"); |
228 | goto Enable_irqs; | 228 | goto Unlock; |
229 | } | 229 | } |
230 | |||
231 | local_irq_disable(); | ||
232 | |||
230 | sysdev_suspend(PMSG_FREEZE); | 233 | sysdev_suspend(PMSG_FREEZE); |
231 | if (error) { | 234 | if (error) { |
232 | printk(KERN_ERR "PM: Some devices failed to power down, " | 235 | printk(KERN_ERR "PM: Some devices failed to power down, " |
@@ -252,12 +255,16 @@ static int create_image(int platform_mode) | |||
252 | /* NOTE: device_power_up() is just a resume() for devices | 255 | /* NOTE: device_power_up() is just a resume() for devices |
253 | * that suspended with irqs off ... no overall powerup. | 256 | * that suspended with irqs off ... no overall powerup. |
254 | */ | 257 | */ |
258 | |||
255 | Power_up_devices: | 259 | Power_up_devices: |
260 | local_irq_enable(); | ||
261 | |||
256 | device_power_up(in_suspend ? | 262 | device_power_up(in_suspend ? |
257 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); | 263 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); |
258 | Enable_irqs: | 264 | |
259 | local_irq_enable(); | 265 | Unlock: |
260 | device_pm_unlock(); | 266 | device_pm_unlock(); |
267 | |||
261 | return error; | 268 | return error; |
262 | } | 269 | } |
263 | 270 | ||
@@ -336,13 +343,16 @@ static int resume_target_kernel(void) | |||
336 | int error; | 343 | int error; |
337 | 344 | ||
338 | device_pm_lock(); | 345 | device_pm_lock(); |
339 | local_irq_disable(); | 346 | |
340 | error = device_power_down(PMSG_QUIESCE); | 347 | error = device_power_down(PMSG_QUIESCE); |
341 | if (error) { | 348 | if (error) { |
342 | printk(KERN_ERR "PM: Some devices failed to power down, " | 349 | printk(KERN_ERR "PM: Some devices failed to power down, " |
343 | "aborting resume\n"); | 350 | "aborting resume\n"); |
344 | goto Enable_irqs; | 351 | goto Unlock; |
345 | } | 352 | } |
353 | |||
354 | local_irq_disable(); | ||
355 | |||
346 | sysdev_suspend(PMSG_QUIESCE); | 356 | sysdev_suspend(PMSG_QUIESCE); |
347 | /* We'll ignore saved state, but this gets preempt count (etc) right */ | 357 | /* We'll ignore saved state, but this gets preempt count (etc) right */ |
348 | save_processor_state(); | 358 | save_processor_state(); |
@@ -366,11 +376,16 @@ static int resume_target_kernel(void) | |||
366 | swsusp_free(); | 376 | swsusp_free(); |
367 | restore_processor_state(); | 377 | restore_processor_state(); |
368 | touch_softlockup_watchdog(); | 378 | touch_softlockup_watchdog(); |
379 | |||
369 | sysdev_resume(); | 380 | sysdev_resume(); |
370 | device_power_up(PMSG_RECOVER); | 381 | |
371 | Enable_irqs: | ||
372 | local_irq_enable(); | 382 | local_irq_enable(); |
383 | |||
384 | device_power_up(PMSG_RECOVER); | ||
385 | |||
386 | Unlock: | ||
373 | device_pm_unlock(); | 387 | device_pm_unlock(); |
388 | |||
374 | return error; | 389 | return error; |
375 | } | 390 | } |
376 | 391 | ||
@@ -447,15 +462,16 @@ int hibernation_platform_enter(void) | |||
447 | goto Finish; | 462 | goto Finish; |
448 | 463 | ||
449 | device_pm_lock(); | 464 | device_pm_lock(); |
450 | local_irq_disable(); | 465 | |
451 | error = device_power_down(PMSG_HIBERNATE); | 466 | error = device_power_down(PMSG_HIBERNATE); |
452 | if (!error) { | 467 | if (!error) { |
468 | local_irq_disable(); | ||
453 | sysdev_suspend(PMSG_HIBERNATE); | 469 | sysdev_suspend(PMSG_HIBERNATE); |
454 | hibernation_ops->enter(); | 470 | hibernation_ops->enter(); |
455 | /* We should never get here */ | 471 | /* We should never get here */ |
456 | while (1); | 472 | while (1); |
457 | } | 473 | } |
458 | local_irq_enable(); | 474 | |
459 | device_pm_unlock(); | 475 | device_pm_unlock(); |
460 | 476 | ||
461 | /* | 477 | /* |
@@ -464,12 +480,15 @@ int hibernation_platform_enter(void) | |||
464 | */ | 480 | */ |
465 | Finish: | 481 | Finish: |
466 | hibernation_ops->finish(); | 482 | hibernation_ops->finish(); |
483 | |||
467 | Resume_devices: | 484 | Resume_devices: |
468 | entering_platform_hibernation = false; | 485 | entering_platform_hibernation = false; |
469 | device_resume(PMSG_RESTORE); | 486 | device_resume(PMSG_RESTORE); |
470 | resume_console(); | 487 | resume_console(); |
488 | |||
471 | Close: | 489 | Close: |
472 | hibernation_ops->end(); | 490 | hibernation_ops->end(); |
491 | |||
473 | return error; | 492 | return error; |
474 | } | 493 | } |
475 | 494 | ||