diff options
Diffstat (limited to 'kernel/power')
-rw-r--r-- | kernel/power/disk.c | 51 | ||||
-rw-r--r-- | kernel/power/main.c | 24 | ||||
-rw-r--r-- | kernel/power/swap.c | 2 |
3 files changed, 44 insertions, 33 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 0854770b63b9..e71ca9cd81b2 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -646,13 +646,6 @@ static int software_resume(void) | |||
646 | return 0; | 646 | return 0; |
647 | 647 | ||
648 | /* | 648 | /* |
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 | 649 | * name_to_dev_t() below takes a sysfs buffer mutex when sysfs |
657 | * is configured into the kernel. Since the regular hibernate | 650 | * is configured into the kernel. Since the regular hibernate |
658 | * trigger path is via sysfs which takes a buffer mutex before | 651 | * trigger path is via sysfs which takes a buffer mutex before |
@@ -663,32 +656,42 @@ static int software_resume(void) | |||
663 | * here to avoid lockdep complaining. | 656 | * here to avoid lockdep complaining. |
664 | */ | 657 | */ |
665 | mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING); | 658 | mutex_lock_nested(&pm_mutex, SINGLE_DEPTH_NESTING); |
659 | |||
660 | if (swsusp_resume_device) | ||
661 | goto Check_image; | ||
662 | |||
663 | if (!strlen(resume_file)) { | ||
664 | error = -ENOENT; | ||
665 | goto Unlock; | ||
666 | } | ||
667 | |||
668 | pr_debug("PM: Checking image partition %s\n", resume_file); | ||
669 | |||
670 | /* Check if the device is there */ | ||
671 | swsusp_resume_device = name_to_dev_t(resume_file); | ||
666 | if (!swsusp_resume_device) { | 672 | if (!swsusp_resume_device) { |
667 | if (!strlen(resume_file)) { | ||
668 | mutex_unlock(&pm_mutex); | ||
669 | return -ENOENT; | ||
670 | } | ||
671 | /* | 673 | /* |
672 | * Some device discovery might still be in progress; we need | 674 | * Some device discovery might still be in progress; we need |
673 | * to wait for this to finish. | 675 | * to wait for this to finish. |
674 | */ | 676 | */ |
675 | wait_for_device_probe(); | 677 | wait_for_device_probe(); |
678 | /* | ||
679 | * We can't depend on SCSI devices being available after loading | ||
680 | * one of their modules until scsi_complete_async_scans() is | ||
681 | * called and the resume device usually is a SCSI one. | ||
682 | */ | ||
683 | scsi_complete_async_scans(); | ||
684 | |||
676 | swsusp_resume_device = name_to_dev_t(resume_file); | 685 | swsusp_resume_device = name_to_dev_t(resume_file); |
677 | pr_debug("PM: Resume from partition %s\n", resume_file); | 686 | if (!swsusp_resume_device) { |
678 | } else { | 687 | error = -ENODEV; |
679 | pr_debug("PM: Resume from partition %d:%d\n", | 688 | goto Unlock; |
680 | MAJOR(swsusp_resume_device), | 689 | } |
681 | MINOR(swsusp_resume_device)); | ||
682 | } | 690 | } |
683 | 691 | ||
684 | if (noresume) { | 692 | Check_image: |
685 | /** | 693 | pr_debug("PM: Resume from partition %d:%d\n", |
686 | * FIXME: If noresume is specified, we need to find the | 694 | 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 | 695 | ||
693 | pr_debug("PM: Checking hibernation image.\n"); | 696 | pr_debug("PM: Checking hibernation image.\n"); |
694 | error = swsusp_check(); | 697 | error = swsusp_check(); |
diff --git a/kernel/power/main.c b/kernel/power/main.c index f172f41858bb..f99ed6a75eac 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -291,20 +291,26 @@ static int suspend_enter(suspend_state_t state) | |||
291 | 291 | ||
292 | device_pm_lock(); | 292 | device_pm_lock(); |
293 | 293 | ||
294 | if (suspend_ops->prepare) { | ||
295 | error = suspend_ops->prepare(); | ||
296 | if (error) | ||
297 | goto Done; | ||
298 | } | ||
299 | |||
294 | error = device_power_down(PMSG_SUSPEND); | 300 | error = device_power_down(PMSG_SUSPEND); |
295 | if (error) { | 301 | if (error) { |
296 | printk(KERN_ERR "PM: Some devices failed to power down\n"); | 302 | printk(KERN_ERR "PM: Some devices failed to power down\n"); |
297 | goto Done; | 303 | goto Platfrom_finish; |
298 | } | 304 | } |
299 | 305 | ||
300 | if (suspend_ops->prepare) { | 306 | if (suspend_ops->prepare_late) { |
301 | error = suspend_ops->prepare(); | 307 | error = suspend_ops->prepare_late(); |
302 | if (error) | 308 | if (error) |
303 | goto Power_up_devices; | 309 | goto Power_up_devices; |
304 | } | 310 | } |
305 | 311 | ||
306 | if (suspend_test(TEST_PLATFORM)) | 312 | if (suspend_test(TEST_PLATFORM)) |
307 | goto Platfrom_finish; | 313 | goto Platform_wake; |
308 | 314 | ||
309 | error = disable_nonboot_cpus(); | 315 | error = disable_nonboot_cpus(); |
310 | if (error || suspend_test(TEST_CPUS)) | 316 | if (error || suspend_test(TEST_CPUS)) |
@@ -326,13 +332,17 @@ static int suspend_enter(suspend_state_t state) | |||
326 | Enable_cpus: | 332 | Enable_cpus: |
327 | enable_nonboot_cpus(); | 333 | enable_nonboot_cpus(); |
328 | 334 | ||
329 | Platfrom_finish: | 335 | Platform_wake: |
330 | if (suspend_ops->finish) | 336 | if (suspend_ops->wake) |
331 | suspend_ops->finish(); | 337 | suspend_ops->wake(); |
332 | 338 | ||
333 | Power_up_devices: | 339 | Power_up_devices: |
334 | device_power_up(PMSG_RESUME); | 340 | device_power_up(PMSG_RESUME); |
335 | 341 | ||
342 | Platfrom_finish: | ||
343 | if (suspend_ops->finish) | ||
344 | suspend_ops->finish(); | ||
345 | |||
336 | Done: | 346 | Done: |
337 | device_pm_unlock(); | 347 | device_pm_unlock(); |
338 | 348 | ||
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 505f319e489c..8ba052c86d48 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -64,8 +64,6 @@ static int submit(int rw, pgoff_t page_off, struct page *page, | |||
64 | struct bio *bio; | 64 | struct bio *bio; |
65 | 65 | ||
66 | bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); | 66 | bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1); |
67 | if (!bio) | ||
68 | return -ENOMEM; | ||
69 | bio->bi_sector = page_off * (PAGE_SIZE >> 9); | 67 | bio->bi_sector = page_off * (PAGE_SIZE >> 9); |
70 | bio->bi_bdev = resume_bdev; | 68 | bio->bi_bdev = resume_bdev; |
71 | bio->bi_end_io = end_swap_bio_read; | 69 | bio->bi_end_io = end_swap_bio_read; |