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); |