diff options
Diffstat (limited to 'kernel/power/hibernate.c')
| -rw-r--r-- | kernel/power/hibernate.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 04b3a83d686f..bbfe472d7524 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
| @@ -32,6 +32,7 @@ static int noresume = 0; | |||
| 32 | static char resume_file[256] = CONFIG_PM_STD_PARTITION; | 32 | static char resume_file[256] = CONFIG_PM_STD_PARTITION; |
| 33 | dev_t swsusp_resume_device; | 33 | dev_t swsusp_resume_device; |
| 34 | sector_t swsusp_resume_block; | 34 | sector_t swsusp_resume_block; |
| 35 | int in_suspend __nosavedata = 0; | ||
| 35 | 36 | ||
| 36 | enum { | 37 | enum { |
| 37 | HIBERNATION_INVALID, | 38 | HIBERNATION_INVALID, |
| @@ -202,6 +203,35 @@ static void platform_recover(int platform_mode) | |||
| 202 | } | 203 | } |
| 203 | 204 | ||
| 204 | /** | 205 | /** |
| 206 | * swsusp_show_speed - print the time elapsed between two events. | ||
| 207 | * @start: Starting event. | ||
| 208 | * @stop: Final event. | ||
| 209 | * @nr_pages - number of pages processed between @start and @stop | ||
| 210 | * @msg - introductory message to print | ||
| 211 | */ | ||
| 212 | |||
| 213 | void swsusp_show_speed(struct timeval *start, struct timeval *stop, | ||
| 214 | unsigned nr_pages, char *msg) | ||
| 215 | { | ||
| 216 | s64 elapsed_centisecs64; | ||
| 217 | int centisecs; | ||
| 218 | int k; | ||
| 219 | int kps; | ||
| 220 | |||
| 221 | elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start); | ||
| 222 | do_div(elapsed_centisecs64, NSEC_PER_SEC / 100); | ||
| 223 | centisecs = elapsed_centisecs64; | ||
| 224 | if (centisecs == 0) | ||
| 225 | centisecs = 1; /* avoid div-by-zero */ | ||
| 226 | k = nr_pages * (PAGE_SIZE / 1024); | ||
| 227 | kps = (k * 100) / centisecs; | ||
| 228 | printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", | ||
| 229 | msg, k, | ||
| 230 | centisecs / 100, centisecs % 100, | ||
| 231 | kps / 1000, (kps % 1000) / 10); | ||
| 232 | } | ||
| 233 | |||
| 234 | /** | ||
| 205 | * create_image - freeze devices that need to be frozen with interrupts | 235 | * create_image - freeze devices that need to be frozen with interrupts |
| 206 | * off, create the hibernation image and thaw those devices. Control | 236 | * off, create the hibernation image and thaw those devices. Control |
| 207 | * reappears in this routine after a restore. | 237 | * reappears in this routine after a restore. |
| @@ -693,21 +723,22 @@ static int software_resume(void) | |||
| 693 | /* The snapshot device should not be opened while we're running */ | 723 | /* The snapshot device should not be opened while we're running */ |
| 694 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { | 724 | if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { |
| 695 | error = -EBUSY; | 725 | error = -EBUSY; |
| 726 | swsusp_close(FMODE_READ); | ||
| 696 | goto Unlock; | 727 | goto Unlock; |
| 697 | } | 728 | } |
| 698 | 729 | ||
| 699 | pm_prepare_console(); | 730 | pm_prepare_console(); |
| 700 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); | 731 | error = pm_notifier_call_chain(PM_RESTORE_PREPARE); |
| 701 | if (error) | 732 | if (error) |
| 702 | goto Finish; | 733 | goto close_finish; |
| 703 | 734 | ||
| 704 | error = usermodehelper_disable(); | 735 | error = usermodehelper_disable(); |
| 705 | if (error) | 736 | if (error) |
| 706 | goto Finish; | 737 | goto close_finish; |
| 707 | 738 | ||
| 708 | error = create_basic_memory_bitmaps(); | 739 | error = create_basic_memory_bitmaps(); |
| 709 | if (error) | 740 | if (error) |
| 710 | goto Finish; | 741 | goto close_finish; |
| 711 | 742 | ||
| 712 | pr_debug("PM: Preparing processes for restore.\n"); | 743 | pr_debug("PM: Preparing processes for restore.\n"); |
| 713 | error = prepare_processes(); | 744 | error = prepare_processes(); |
| @@ -719,6 +750,7 @@ static int software_resume(void) | |||
| 719 | pr_debug("PM: Reading hibernation image.\n"); | 750 | pr_debug("PM: Reading hibernation image.\n"); |
| 720 | 751 | ||
| 721 | error = swsusp_read(&flags); | 752 | error = swsusp_read(&flags); |
| 753 | swsusp_close(FMODE_READ); | ||
| 722 | if (!error) | 754 | if (!error) |
| 723 | hibernation_restore(flags & SF_PLATFORM_MODE); | 755 | hibernation_restore(flags & SF_PLATFORM_MODE); |
| 724 | 756 | ||
| @@ -737,6 +769,9 @@ static int software_resume(void) | |||
| 737 | mutex_unlock(&pm_mutex); | 769 | mutex_unlock(&pm_mutex); |
| 738 | pr_debug("PM: Resume from disk failed.\n"); | 770 | pr_debug("PM: Resume from disk failed.\n"); |
| 739 | return error; | 771 | return error; |
| 772 | close_finish: | ||
| 773 | swsusp_close(FMODE_READ); | ||
| 774 | goto Finish; | ||
| 740 | } | 775 | } |
| 741 | 776 | ||
| 742 | late_initcall(software_resume); | 777 | late_initcall(software_resume); |
