diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kexec.c | 8 | ||||
-rw-r--r-- | kernel/power/disk.c | 39 | ||||
-rw-r--r-- | kernel/power/main.c | 17 |
3 files changed, 44 insertions, 20 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c index c7fd6692939d..dade9af6bf21 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -1454,7 +1454,6 @@ int kernel_kexec(void) | |||
1454 | if (error) | 1454 | if (error) |
1455 | goto Resume_devices; | 1455 | goto Resume_devices; |
1456 | device_pm_lock(); | 1456 | device_pm_lock(); |
1457 | local_irq_disable(); | ||
1458 | /* At this point, device_suspend() has been called, | 1457 | /* At this point, device_suspend() has been called, |
1459 | * but *not* device_power_down(). We *must* | 1458 | * but *not* device_power_down(). We *must* |
1460 | * device_power_down() now. Otherwise, drivers for | 1459 | * device_power_down() now. Otherwise, drivers for |
@@ -1464,8 +1463,9 @@ int kernel_kexec(void) | |||
1464 | */ | 1463 | */ |
1465 | error = device_power_down(PMSG_FREEZE); | 1464 | error = device_power_down(PMSG_FREEZE); |
1466 | if (error) | 1465 | if (error) |
1467 | goto Enable_irqs; | 1466 | goto Unlock_pm; |
1468 | 1467 | ||
1468 | local_irq_disable(); | ||
1469 | /* Suspend system devices */ | 1469 | /* Suspend system devices */ |
1470 | error = sysdev_suspend(PMSG_FREEZE); | 1470 | error = sysdev_suspend(PMSG_FREEZE); |
1471 | if (error) | 1471 | if (error) |
@@ -1484,9 +1484,9 @@ int kernel_kexec(void) | |||
1484 | if (kexec_image->preserve_context) { | 1484 | if (kexec_image->preserve_context) { |
1485 | sysdev_resume(); | 1485 | sysdev_resume(); |
1486 | Power_up_devices: | 1486 | Power_up_devices: |
1487 | device_power_up(PMSG_RESTORE); | ||
1488 | Enable_irqs: | ||
1489 | local_irq_enable(); | 1487 | local_irq_enable(); |
1488 | device_power_up(PMSG_RESTORE); | ||
1489 | Unlock_pm: | ||
1490 | device_pm_unlock(); | 1490 | device_pm_unlock(); |
1491 | enable_nonboot_cpus(); | 1491 | enable_nonboot_cpus(); |
1492 | Resume_devices: | 1492 | Resume_devices: |
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 | ||
diff --git a/kernel/power/main.c b/kernel/power/main.c index c9632f841f64..f0a466736c01 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -287,17 +287,19 @@ 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 | error = device_power_down(PMSG_SUSPEND); |
295 | if (error) { | ||
297 | printk(KERN_ERR "PM: Some devices failed to power down\n"); | 296 | printk(KERN_ERR "PM: Some devices failed to power down\n"); |
298 | goto Done; | 297 | goto Done; |
299 | } | 298 | } |
300 | 299 | ||
300 | arch_suspend_disable_irqs(); | ||
301 | BUG_ON(!irqs_disabled()); | ||
302 | |||
301 | error = sysdev_suspend(PMSG_SUSPEND); | 303 | error = sysdev_suspend(PMSG_SUSPEND); |
302 | if (!error) { | 304 | if (!error) { |
303 | if (!suspend_test(TEST_CORE)) | 305 | if (!suspend_test(TEST_CORE)) |
@@ -305,11 +307,14 @@ static int suspend_enter(suspend_state_t state) | |||
305 | sysdev_resume(); | 307 | sysdev_resume(); |
306 | } | 308 | } |
307 | 309 | ||
308 | device_power_up(PMSG_RESUME); | ||
309 | Done: | ||
310 | arch_suspend_enable_irqs(); | 310 | arch_suspend_enable_irqs(); |
311 | BUG_ON(irqs_disabled()); | 311 | BUG_ON(irqs_disabled()); |
312 | |||
313 | device_power_up(PMSG_RESUME); | ||
314 | |||
315 | Done: | ||
312 | device_pm_unlock(); | 316 | device_pm_unlock(); |
317 | |||
313 | return error; | 318 | return error; |
314 | } | 319 | } |
315 | 320 | ||