aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r--kernel/power/disk.c76
1 files changed, 32 insertions, 44 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 0854770b63b9..5cb080e7eebd 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -215,8 +215,6 @@ static int create_image(int platform_mode)
215 if (error) 215 if (error)
216 return error; 216 return error;
217 217
218 device_pm_lock();
219
220 /* At this point, device_suspend() has been called, but *not* 218 /* At this point, device_suspend() has been called, but *not*
221 * device_power_down(). We *must* call device_power_down() now. 219 * device_power_down(). We *must* call device_power_down() now.
222 * Otherwise, drivers for some devices (e.g. interrupt controllers) 220 * Otherwise, drivers for some devices (e.g. interrupt controllers)
@@ -227,7 +225,7 @@ static int create_image(int platform_mode)
227 if (error) { 225 if (error) {
228 printk(KERN_ERR "PM: Some devices failed to power down, " 226 printk(KERN_ERR "PM: Some devices failed to power down, "
229 "aborting hibernation\n"); 227 "aborting hibernation\n");
230 goto Unlock; 228 return error;
231 } 229 }
232 230
233 error = platform_pre_snapshot(platform_mode); 231 error = platform_pre_snapshot(platform_mode);
@@ -241,9 +239,9 @@ static int create_image(int platform_mode)
241 239
242 local_irq_disable(); 240 local_irq_disable();
243 241
244 sysdev_suspend(PMSG_FREEZE); 242 error = sysdev_suspend(PMSG_FREEZE);
245 if (error) { 243 if (error) {
246 printk(KERN_ERR "PM: Some devices failed to power down, " 244 printk(KERN_ERR "PM: Some system devices failed to power down, "
247 "aborting hibernation\n"); 245 "aborting hibernation\n");
248 goto Enable_irqs; 246 goto Enable_irqs;
249 } 247 }
@@ -280,9 +278,6 @@ static int create_image(int platform_mode)
280 device_power_up(in_suspend ? 278 device_power_up(in_suspend ?
281 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 279 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
282 280
283 Unlock:
284 device_pm_unlock();
285
286 return error; 281 return error;
287} 282}
288 283
@@ -344,13 +339,11 @@ static int resume_target_kernel(bool platform_mode)
344{ 339{
345 int error; 340 int error;
346 341
347 device_pm_lock();
348
349 error = device_power_down(PMSG_QUIESCE); 342 error = device_power_down(PMSG_QUIESCE);
350 if (error) { 343 if (error) {
351 printk(KERN_ERR "PM: Some devices failed to power down, " 344 printk(KERN_ERR "PM: Some devices failed to power down, "
352 "aborting resume\n"); 345 "aborting resume\n");
353 goto Unlock; 346 return error;
354 } 347 }
355 348
356 error = platform_pre_restore(platform_mode); 349 error = platform_pre_restore(platform_mode);
@@ -403,9 +396,6 @@ static int resume_target_kernel(bool platform_mode)
403 396
404 device_power_up(PMSG_RECOVER); 397 device_power_up(PMSG_RECOVER);
405 398
406 Unlock:
407 device_pm_unlock();
408
409 return error; 399 return error;
410} 400}
411 401
@@ -464,11 +454,9 @@ int hibernation_platform_enter(void)
464 goto Resume_devices; 454 goto Resume_devices;
465 } 455 }
466 456
467 device_pm_lock();
468
469 error = device_power_down(PMSG_HIBERNATE); 457 error = device_power_down(PMSG_HIBERNATE);
470 if (error) 458 if (error)
471 goto Unlock; 459 goto Resume_devices;
472 460
473 error = hibernation_ops->prepare(); 461 error = hibernation_ops->prepare();
474 if (error) 462 if (error)
@@ -493,9 +481,6 @@ int hibernation_platform_enter(void)
493 481
494 device_power_up(PMSG_RESTORE); 482 device_power_up(PMSG_RESTORE);
495 483
496 Unlock:
497 device_pm_unlock();
498
499 Resume_devices: 484 Resume_devices:
500 entering_platform_hibernation = false; 485 entering_platform_hibernation = false;
501 device_resume(PMSG_RESTORE); 486 device_resume(PMSG_RESTORE);
@@ -646,13 +631,6 @@ static int software_resume(void)
646 return 0; 631 return 0;
647 632
648 /* 633 /*
649 * We can't depend on SCSI devices being available after loading one of
650 * their modules if scsi_complete_async_scans() is not called and the
651 * resume device usually is a SCSI one.
652 */
653 scsi_complete_async_scans();
654
655 /*
656 * name_to_dev_t() below takes a sysfs buffer mutex when sysfs 634 * name_to_dev_t() below takes a sysfs buffer mutex when sysfs
657 * is configured into the kernel. Since the regular hibernate 635 * is configured into the kernel. Since the regular hibernate
658 * trigger path is via sysfs which takes a buffer mutex before 636 * trigger path is via sysfs which takes a buffer mutex before
@@ -663,32 +641,42 @@ static int software_resume(void)
663 * here to avoid lockdep complaining. 641 * here to avoid lockdep complaining.
664 */ 642 */
665 mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING); 643 mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING);
644
645 if (swsusp_resume_device)
646 goto Check_image;
647
648 if (!strlen(resume_file)) {
649 error = -ENOENT;
650 goto Unlock;
651 }
652
653 pr_debug("PM: Checking image partition %s\n", resume_file);
654
655 /* Check if the device is there */
656 swsusp_resume_device = name_to_dev_t(resume_file);
666 if (!swsusp_resume_device) { 657 if (!swsusp_resume_device) {
667 if (!strlen(resume_file)) {
668 mutex_unlock(&pm_mutex);
669 return -ENOENT;
670 }
671 /* 658 /*
672 * Some device discovery might still be in progress; we need 659 * Some device discovery might still be in progress; we need
673 * to wait for this to finish. 660 * to wait for this to finish.
674 */ 661 */
675 wait_for_device_probe(); 662 wait_for_device_probe();
663 /*
664 * We can't depend on SCSI devices being available after loading
665 * one of their modules until scsi_complete_async_scans() is
666 * called and the resume device usually is a SCSI one.
667 */
668 scsi_complete_async_scans();
669
676 swsusp_resume_device = name_to_dev_t(resume_file); 670 swsusp_resume_device = name_to_dev_t(resume_file);
677 pr_debug("PM: Resume from partition %s\n", resume_file); 671 if (!swsusp_resume_device) {
678 } else { 672 error = -ENODEV;
679 pr_debug("PM: Resume from partition %d:%d\n", 673 goto Unlock;
680 MAJOR(swsusp_resume_device), 674 }
681 MINOR(swsusp_resume_device));
682 } 675 }
683 676
684 if (noresume) { 677 Check_image:
685 /** 678 pr_debug("PM: Resume from partition %d:%d\n",
686 * FIXME: If noresume is specified, we need to find the 679 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
687 * partition and reset it back to normal swap space.
688 */
689 mutex_unlock(&pm_mutex);
690 return 0;
691 }
692 680
693 pr_debug("PM: Checking hibernation image.\n"); 681 pr_debug("PM: Checking hibernation image.\n");
694 error = swsusp_check(); 682 error = swsusp_check();