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.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 1832bd264219..f9bec56d8825 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -23,6 +23,7 @@
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 <linux/gfp.h>
26#include <linux/syscore_ops.h>
26#include <scsi/scsi_scan.h> 27#include <scsi/scsi_scan.h>
27#include <asm/suspend.h> 28#include <asm/suspend.h>
28 29
@@ -271,7 +272,7 @@ static int create_image(int platform_mode)
271 272
272 local_irq_disable(); 273 local_irq_disable();
273 274
274 error = sysdev_suspend(PMSG_FREEZE); 275 error = syscore_suspend();
275 if (error) { 276 if (error) {
276 printk(KERN_ERR "PM: Some system devices failed to power down, " 277 printk(KERN_ERR "PM: Some system devices failed to power down, "
277 "aborting hibernation\n"); 278 "aborting hibernation\n");
@@ -295,7 +296,7 @@ static int create_image(int platform_mode)
295 } 296 }
296 297
297 Power_up: 298 Power_up:
298 sysdev_resume(); 299 syscore_resume();
299 /* NOTE: dpm_resume_noirq() is just a resume() for devices 300 /* NOTE: dpm_resume_noirq() is just a resume() for devices
300 * that suspended with irqs off ... no overall powerup. 301 * that suspended with irqs off ... no overall powerup.
301 */ 302 */
@@ -326,20 +327,25 @@ static int create_image(int platform_mode)
326 327
327int hibernation_snapshot(int platform_mode) 328int hibernation_snapshot(int platform_mode)
328{ 329{
330 pm_message_t msg = PMSG_RECOVER;
329 int error; 331 int error;
330 332
331 error = platform_begin(platform_mode); 333 error = platform_begin(platform_mode);
332 if (error) 334 if (error)
333 goto Close; 335 goto Close;
334 336
337 error = dpm_prepare(PMSG_FREEZE);
338 if (error)
339 goto Complete_devices;
340
335 /* Preallocate image memory before shutting down devices. */ 341 /* Preallocate image memory before shutting down devices. */
336 error = hibernate_preallocate_memory(); 342 error = hibernate_preallocate_memory();
337 if (error) 343 if (error)
338 goto Close; 344 goto Complete_devices;
339 345
340 suspend_console(); 346 suspend_console();
341 pm_restrict_gfp_mask(); 347 pm_restrict_gfp_mask();
342 error = dpm_suspend_start(PMSG_FREEZE); 348 error = dpm_suspend(PMSG_FREEZE);
343 if (error) 349 if (error)
344 goto Recover_platform; 350 goto Recover_platform;
345 351
@@ -357,13 +363,17 @@ int hibernation_snapshot(int platform_mode)
357 if (error || !in_suspend) 363 if (error || !in_suspend)
358 swsusp_free(); 364 swsusp_free();
359 365
360 dpm_resume_end(in_suspend ? 366 msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
361 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 367 dpm_resume(msg);
362 368
363 if (error || !in_suspend) 369 if (error || !in_suspend)
364 pm_restore_gfp_mask(); 370 pm_restore_gfp_mask();
365 371
366 resume_console(); 372 resume_console();
373
374 Complete_devices:
375 dpm_complete(msg);
376
367 Close: 377 Close:
368 platform_end(platform_mode); 378 platform_end(platform_mode);
369 return error; 379 return error;
@@ -402,7 +412,7 @@ static int resume_target_kernel(bool platform_mode)
402 412
403 local_irq_disable(); 413 local_irq_disable();
404 414
405 error = sysdev_suspend(PMSG_QUIESCE); 415 error = syscore_suspend();
406 if (error) 416 if (error)
407 goto Enable_irqs; 417 goto Enable_irqs;
408 418
@@ -429,7 +439,7 @@ static int resume_target_kernel(bool platform_mode)
429 restore_processor_state(); 439 restore_processor_state();
430 touch_softlockup_watchdog(); 440 touch_softlockup_watchdog();
431 441
432 sysdev_resume(); 442 syscore_resume();
433 443
434 Enable_irqs: 444 Enable_irqs:
435 local_irq_enable(); 445 local_irq_enable();
@@ -515,7 +525,7 @@ int hibernation_platform_enter(void)
515 goto Platform_finish; 525 goto Platform_finish;
516 526
517 local_irq_disable(); 527 local_irq_disable();
518 sysdev_suspend(PMSG_HIBERNATE); 528 syscore_suspend();
519 if (pm_wakeup_pending()) { 529 if (pm_wakeup_pending()) {
520 error = -EAGAIN; 530 error = -EAGAIN;
521 goto Power_up; 531 goto Power_up;
@@ -526,7 +536,7 @@ int hibernation_platform_enter(void)
526 while (1); 536 while (1);
527 537
528 Power_up: 538 Power_up:
529 sysdev_resume(); 539 syscore_resume();
530 local_irq_enable(); 540 local_irq_enable();
531 enable_nonboot_cpus(); 541 enable_nonboot_cpus();
532 542
@@ -967,10 +977,33 @@ static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *att
967 977
968power_attr(image_size); 978power_attr(image_size);
969 979
980static ssize_t reserved_size_show(struct kobject *kobj,
981 struct kobj_attribute *attr, char *buf)
982{
983 return sprintf(buf, "%lu\n", reserved_size);
984}
985
986static ssize_t reserved_size_store(struct kobject *kobj,
987 struct kobj_attribute *attr,
988 const char *buf, size_t n)
989{
990 unsigned long size;
991
992 if (sscanf(buf, "%lu", &size) == 1) {
993 reserved_size = size;
994 return n;
995 }
996
997 return -EINVAL;
998}
999
1000power_attr(reserved_size);
1001
970static struct attribute * g[] = { 1002static struct attribute * g[] = {
971 &disk_attr.attr, 1003 &disk_attr.attr,
972 &resume_attr.attr, 1004 &resume_attr.attr,
973 &image_size_attr.attr, 1005 &image_size_attr.attr,
1006 &reserved_size_attr.attr,
974 NULL, 1007 NULL,
975}; 1008};
976 1009