diff options
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r-- | kernel/power/hibernate.c | 53 |
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 | ||
327 | int hibernation_snapshot(int platform_mode) | 328 | int 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 | ||
968 | power_attr(image_size); | 978 | power_attr(image_size); |
969 | 979 | ||
980 | static 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 | |||
986 | static 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 | |||
1000 | power_attr(reserved_size); | ||
1001 | |||
970 | static struct attribute * g[] = { | 1002 | static 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 | ||