diff options
Diffstat (limited to 'kernel/power/hibernate.c')
-rw-r--r-- | kernel/power/hibernate.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index aeabd26e334..f9bec56d882 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
@@ -272,9 +272,7 @@ static int create_image(int platform_mode) | |||
272 | 272 | ||
273 | local_irq_disable(); | 273 | local_irq_disable(); |
274 | 274 | ||
275 | error = sysdev_suspend(PMSG_FREEZE); | 275 | error = syscore_suspend(); |
276 | if (!error) | ||
277 | error = syscore_suspend(); | ||
278 | if (error) { | 276 | if (error) { |
279 | printk(KERN_ERR "PM: Some system devices failed to power down, " | 277 | printk(KERN_ERR "PM: Some system devices failed to power down, " |
280 | "aborting hibernation\n"); | 278 | "aborting hibernation\n"); |
@@ -299,7 +297,6 @@ static int create_image(int platform_mode) | |||
299 | 297 | ||
300 | Power_up: | 298 | Power_up: |
301 | syscore_resume(); | 299 | syscore_resume(); |
302 | sysdev_resume(); | ||
303 | /* NOTE: dpm_resume_noirq() is just a resume() for devices | 300 | /* NOTE: dpm_resume_noirq() is just a resume() for devices |
304 | * that suspended with irqs off ... no overall powerup. | 301 | * that suspended with irqs off ... no overall powerup. |
305 | */ | 302 | */ |
@@ -330,20 +327,25 @@ static int create_image(int platform_mode) | |||
330 | 327 | ||
331 | int hibernation_snapshot(int platform_mode) | 328 | int hibernation_snapshot(int platform_mode) |
332 | { | 329 | { |
330 | pm_message_t msg = PMSG_RECOVER; | ||
333 | int error; | 331 | int error; |
334 | 332 | ||
335 | error = platform_begin(platform_mode); | 333 | error = platform_begin(platform_mode); |
336 | if (error) | 334 | if (error) |
337 | goto Close; | 335 | goto Close; |
338 | 336 | ||
337 | error = dpm_prepare(PMSG_FREEZE); | ||
338 | if (error) | ||
339 | goto Complete_devices; | ||
340 | |||
339 | /* Preallocate image memory before shutting down devices. */ | 341 | /* Preallocate image memory before shutting down devices. */ |
340 | error = hibernate_preallocate_memory(); | 342 | error = hibernate_preallocate_memory(); |
341 | if (error) | 343 | if (error) |
342 | goto Close; | 344 | goto Complete_devices; |
343 | 345 | ||
344 | suspend_console(); | 346 | suspend_console(); |
345 | pm_restrict_gfp_mask(); | 347 | pm_restrict_gfp_mask(); |
346 | error = dpm_suspend_start(PMSG_FREEZE); | 348 | error = dpm_suspend(PMSG_FREEZE); |
347 | if (error) | 349 | if (error) |
348 | goto Recover_platform; | 350 | goto Recover_platform; |
349 | 351 | ||
@@ -361,13 +363,17 @@ int hibernation_snapshot(int platform_mode) | |||
361 | if (error || !in_suspend) | 363 | if (error || !in_suspend) |
362 | swsusp_free(); | 364 | swsusp_free(); |
363 | 365 | ||
364 | dpm_resume_end(in_suspend ? | 366 | msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE; |
365 | (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); | 367 | dpm_resume(msg); |
366 | 368 | ||
367 | if (error || !in_suspend) | 369 | if (error || !in_suspend) |
368 | pm_restore_gfp_mask(); | 370 | pm_restore_gfp_mask(); |
369 | 371 | ||
370 | resume_console(); | 372 | resume_console(); |
373 | |||
374 | Complete_devices: | ||
375 | dpm_complete(msg); | ||
376 | |||
371 | Close: | 377 | Close: |
372 | platform_end(platform_mode); | 378 | platform_end(platform_mode); |
373 | return error; | 379 | return error; |
@@ -406,9 +412,7 @@ static int resume_target_kernel(bool platform_mode) | |||
406 | 412 | ||
407 | local_irq_disable(); | 413 | local_irq_disable(); |
408 | 414 | ||
409 | error = sysdev_suspend(PMSG_QUIESCE); | 415 | error = syscore_suspend(); |
410 | if (!error) | ||
411 | error = syscore_suspend(); | ||
412 | if (error) | 416 | if (error) |
413 | goto Enable_irqs; | 417 | goto Enable_irqs; |
414 | 418 | ||
@@ -436,7 +440,6 @@ static int resume_target_kernel(bool platform_mode) | |||
436 | touch_softlockup_watchdog(); | 440 | touch_softlockup_watchdog(); |
437 | 441 | ||
438 | syscore_resume(); | 442 | syscore_resume(); |
439 | sysdev_resume(); | ||
440 | 443 | ||
441 | Enable_irqs: | 444 | Enable_irqs: |
442 | local_irq_enable(); | 445 | local_irq_enable(); |
@@ -522,7 +525,6 @@ int hibernation_platform_enter(void) | |||
522 | goto Platform_finish; | 525 | goto Platform_finish; |
523 | 526 | ||
524 | local_irq_disable(); | 527 | local_irq_disable(); |
525 | sysdev_suspend(PMSG_HIBERNATE); | ||
526 | syscore_suspend(); | 528 | syscore_suspend(); |
527 | if (pm_wakeup_pending()) { | 529 | if (pm_wakeup_pending()) { |
528 | error = -EAGAIN; | 530 | error = -EAGAIN; |
@@ -535,7 +537,6 @@ int hibernation_platform_enter(void) | |||
535 | 537 | ||
536 | Power_up: | 538 | Power_up: |
537 | syscore_resume(); | 539 | syscore_resume(); |
538 | sysdev_resume(); | ||
539 | local_irq_enable(); | 540 | local_irq_enable(); |
540 | enable_nonboot_cpus(); | 541 | enable_nonboot_cpus(); |
541 | 542 | ||
@@ -976,10 +977,33 @@ static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *att | |||
976 | 977 | ||
977 | power_attr(image_size); | 978 | power_attr(image_size); |
978 | 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 | |||
979 | static struct attribute * g[] = { | 1002 | static struct attribute * g[] = { |
980 | &disk_attr.attr, | 1003 | &disk_attr.attr, |
981 | &resume_attr.attr, | 1004 | &resume_attr.attr, |
982 | &image_size_attr.attr, | 1005 | &image_size_attr.attr, |
1006 | &reserved_size_attr.attr, | ||
983 | NULL, | 1007 | NULL, |
984 | }; | 1008 | }; |
985 | 1009 | ||