aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/hibernate.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /kernel/power/hibernate.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r--kernel/power/hibernate.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 04a9e90d248f..aa9e916da4d5 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -22,6 +22,7 @@
22#include <linux/console.h> 22#include <linux/console.h>
23#include <linux/cpu.h> 23#include <linux/cpu.h>
24#include <linux/freezer.h> 24#include <linux/freezer.h>
25#include <linux/gfp.h>
25#include <scsi/scsi_scan.h> 26#include <scsi/scsi_scan.h>
26#include <asm/suspend.h> 27#include <asm/suspend.h>
27 28
@@ -32,6 +33,7 @@ static int noresume = 0;
32static char resume_file[256] = CONFIG_PM_STD_PARTITION; 33static char resume_file[256] = CONFIG_PM_STD_PARTITION;
33dev_t swsusp_resume_device; 34dev_t swsusp_resume_device;
34sector_t swsusp_resume_block; 35sector_t swsusp_resume_block;
36int in_suspend __nosavedata = 0;
35 37
36enum { 38enum {
37 HIBERNATION_INVALID, 39 HIBERNATION_INVALID,
@@ -202,6 +204,35 @@ static void platform_recover(int platform_mode)
202} 204}
203 205
204/** 206/**
207 * swsusp_show_speed - print the time elapsed between two events.
208 * @start: Starting event.
209 * @stop: Final event.
210 * @nr_pages - number of pages processed between @start and @stop
211 * @msg - introductory message to print
212 */
213
214void swsusp_show_speed(struct timeval *start, struct timeval *stop,
215 unsigned nr_pages, char *msg)
216{
217 s64 elapsed_centisecs64;
218 int centisecs;
219 int k;
220 int kps;
221
222 elapsed_centisecs64 = timeval_to_ns(stop) - timeval_to_ns(start);
223 do_div(elapsed_centisecs64, NSEC_PER_SEC / 100);
224 centisecs = elapsed_centisecs64;
225 if (centisecs == 0)
226 centisecs = 1; /* avoid div-by-zero */
227 k = nr_pages * (PAGE_SIZE / 1024);
228 kps = (k * 100) / centisecs;
229 printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n",
230 msg, k,
231 centisecs / 100, centisecs % 100,
232 kps / 1000, (kps % 1000) / 10);
233}
234
235/**
205 * create_image - freeze devices that need to be frozen with interrupts 236 * create_image - freeze devices that need to be frozen with interrupts
206 * off, create the hibernation image and thaw those devices. Control 237 * off, create the hibernation image and thaw those devices. Control
207 * reappears in this routine after a restore. 238 * reappears in this routine after a restore.
@@ -293,6 +324,7 @@ static int create_image(int platform_mode)
293int hibernation_snapshot(int platform_mode) 324int hibernation_snapshot(int platform_mode)
294{ 325{
295 int error; 326 int error;
327 gfp_t saved_mask;
296 328
297 error = platform_begin(platform_mode); 329 error = platform_begin(platform_mode);
298 if (error) 330 if (error)
@@ -304,6 +336,7 @@ int hibernation_snapshot(int platform_mode)
304 goto Close; 336 goto Close;
305 337
306 suspend_console(); 338 suspend_console();
339 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
307 error = dpm_suspend_start(PMSG_FREEZE); 340 error = dpm_suspend_start(PMSG_FREEZE);
308 if (error) 341 if (error)
309 goto Recover_platform; 342 goto Recover_platform;
@@ -321,6 +354,7 @@ int hibernation_snapshot(int platform_mode)
321 354
322 dpm_resume_end(in_suspend ? 355 dpm_resume_end(in_suspend ?
323 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 356 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
357 set_gfp_allowed_mask(saved_mask);
324 resume_console(); 358 resume_console();
325 Close: 359 Close:
326 platform_end(platform_mode); 360 platform_end(platform_mode);
@@ -415,14 +449,17 @@ static int resume_target_kernel(bool platform_mode)
415int hibernation_restore(int platform_mode) 449int hibernation_restore(int platform_mode)
416{ 450{
417 int error; 451 int error;
452 gfp_t saved_mask;
418 453
419 pm_prepare_console(); 454 pm_prepare_console();
420 suspend_console(); 455 suspend_console();
456 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
421 error = dpm_suspend_start(PMSG_QUIESCE); 457 error = dpm_suspend_start(PMSG_QUIESCE);
422 if (!error) { 458 if (!error) {
423 error = resume_target_kernel(platform_mode); 459 error = resume_target_kernel(platform_mode);
424 dpm_resume_end(PMSG_RECOVER); 460 dpm_resume_end(PMSG_RECOVER);
425 } 461 }
462 set_gfp_allowed_mask(saved_mask);
426 resume_console(); 463 resume_console();
427 pm_restore_console(); 464 pm_restore_console();
428 return error; 465 return error;
@@ -436,6 +473,7 @@ int hibernation_restore(int platform_mode)
436int hibernation_platform_enter(void) 473int hibernation_platform_enter(void)
437{ 474{
438 int error; 475 int error;
476 gfp_t saved_mask;
439 477
440 if (!hibernation_ops) 478 if (!hibernation_ops)
441 return -ENOSYS; 479 return -ENOSYS;
@@ -451,6 +489,7 @@ int hibernation_platform_enter(void)
451 489
452 entering_platform_hibernation = true; 490 entering_platform_hibernation = true;
453 suspend_console(); 491 suspend_console();
492 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
454 error = dpm_suspend_start(PMSG_HIBERNATE); 493 error = dpm_suspend_start(PMSG_HIBERNATE);
455 if (error) { 494 if (error) {
456 if (hibernation_ops->recover) 495 if (hibernation_ops->recover)
@@ -488,6 +527,7 @@ int hibernation_platform_enter(void)
488 Resume_devices: 527 Resume_devices:
489 entering_platform_hibernation = false; 528 entering_platform_hibernation = false;
490 dpm_resume_end(PMSG_RESTORE); 529 dpm_resume_end(PMSG_RESTORE);
530 set_gfp_allowed_mask(saved_mask);
491 resume_console(); 531 resume_console();
492 532
493 Close: 533 Close: