aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 04a9e90d248f..da5288ec2392 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -32,6 +32,7 @@ static int noresume = 0;
32static char resume_file[256] = CONFIG_PM_STD_PARTITION; 32static char resume_file[256] = CONFIG_PM_STD_PARTITION;
33dev_t swsusp_resume_device; 33dev_t swsusp_resume_device;
34sector_t swsusp_resume_block; 34sector_t swsusp_resume_block;
35int in_suspend __nosavedata = 0;
35 36
36enum { 37enum {
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
213void 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.
@@ -293,6 +323,7 @@ static int create_image(int platform_mode)
293int hibernation_snapshot(int platform_mode) 323int hibernation_snapshot(int platform_mode)
294{ 324{
295 int error; 325 int error;
326 gfp_t saved_mask;
296 327
297 error = platform_begin(platform_mode); 328 error = platform_begin(platform_mode);
298 if (error) 329 if (error)
@@ -304,6 +335,7 @@ int hibernation_snapshot(int platform_mode)
304 goto Close; 335 goto Close;
305 336
306 suspend_console(); 337 suspend_console();
338 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
307 error = dpm_suspend_start(PMSG_FREEZE); 339 error = dpm_suspend_start(PMSG_FREEZE);
308 if (error) 340 if (error)
309 goto Recover_platform; 341 goto Recover_platform;
@@ -321,6 +353,7 @@ int hibernation_snapshot(int platform_mode)
321 353
322 dpm_resume_end(in_suspend ? 354 dpm_resume_end(in_suspend ?
323 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 355 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
356 set_gfp_allowed_mask(saved_mask);
324 resume_console(); 357 resume_console();
325 Close: 358 Close:
326 platform_end(platform_mode); 359 platform_end(platform_mode);
@@ -415,14 +448,17 @@ static int resume_target_kernel(bool platform_mode)
415int hibernation_restore(int platform_mode) 448int hibernation_restore(int platform_mode)
416{ 449{
417 int error; 450 int error;
451 gfp_t saved_mask;
418 452
419 pm_prepare_console(); 453 pm_prepare_console();
420 suspend_console(); 454 suspend_console();
455 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
421 error = dpm_suspend_start(PMSG_QUIESCE); 456 error = dpm_suspend_start(PMSG_QUIESCE);
422 if (!error) { 457 if (!error) {
423 error = resume_target_kernel(platform_mode); 458 error = resume_target_kernel(platform_mode);
424 dpm_resume_end(PMSG_RECOVER); 459 dpm_resume_end(PMSG_RECOVER);
425 } 460 }
461 set_gfp_allowed_mask(saved_mask);
426 resume_console(); 462 resume_console();
427 pm_restore_console(); 463 pm_restore_console();
428 return error; 464 return error;
@@ -436,6 +472,7 @@ int hibernation_restore(int platform_mode)
436int hibernation_platform_enter(void) 472int hibernation_platform_enter(void)
437{ 473{
438 int error; 474 int error;
475 gfp_t saved_mask;
439 476
440 if (!hibernation_ops) 477 if (!hibernation_ops)
441 return -ENOSYS; 478 return -ENOSYS;
@@ -451,6 +488,7 @@ int hibernation_platform_enter(void)
451 488
452 entering_platform_hibernation = true; 489 entering_platform_hibernation = true;
453 suspend_console(); 490 suspend_console();
491 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
454 error = dpm_suspend_start(PMSG_HIBERNATE); 492 error = dpm_suspend_start(PMSG_HIBERNATE);
455 if (error) { 493 if (error) {
456 if (hibernation_ops->recover) 494 if (hibernation_ops->recover)
@@ -488,6 +526,7 @@ int hibernation_platform_enter(void)
488 Resume_devices: 526 Resume_devices:
489 entering_platform_hibernation = false; 527 entering_platform_hibernation = false;
490 dpm_resume_end(PMSG_RESTORE); 528 dpm_resume_end(PMSG_RESTORE);
529 set_gfp_allowed_mask(saved_mask);
491 resume_console(); 530 resume_console();
492 531
493 Close: 532 Close: