diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-22 16:36:52 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-22 16:36:52 -0400 |
| commit | 7100e505b76b4e2efd88b2459d1a932214e29f8a (patch) | |
| tree | a8eae8687dc1511c89463b1eb93c8349a7471ab3 /kernel | |
| parent | cb47c1831fa406c964468b259f2082c16cc3f757 (diff) | |
| parent | 75a4161a58dd157a2bd2dc8e9986e45b62ac46cf (diff) | |
Merge tag 'pm-for-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki:
- ACPI conversion to PM handling based on struct dev_pm_ops.
- Conversion of a number of platform drivers to PM handling based on
struct dev_pm_ops and removal of empty legacy PM callbacks from a
couple of PCI drivers.
- Suspend-to-both for in-kernel hibernation from Bojan Smojver.
- cpuidle fixes and cleanups from ShuoX Liu, Daniel Lezcano and Preeti
Murthy.
- cpufreq bug fixes from Jonghwa Lee and Stephen Boyd.
- Suspend and hibernate fixes from Srivatsa Bhat and Colin Cross.
- Generic PM domains framework updates.
- RTC CMOS wakeup signaling update from Paul Fox.
- sparse warnings fixes from Sachin Kamat.
- Build warnings fixes for the generic PM domains framework and PM
sysfs code.
- sysfs switch for printing device suspend times from Sameer Nanda.
- Documentation fix from Oskar Schirmer.
* tag 'pm-for-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (70 commits)
cpufreq: Fix sysfs deadlock with concurrent hotplug/frequency switch
EXYNOS: bugfix on retrieving old_index from freqs.old
PM / Sleep: call early resume handlers when suspend_noirq fails
PM / QoS: Use NULL pointer instead of plain integer in qos.c
PM / QoS: Use NULL pointer instead of plain integer in pm_qos.h
PM / Sleep: Require CAP_BLOCK_SUSPEND to use wake_lock/wake_unlock
PM / Sleep: Add missing static storage class specifiers in main.c
cpuilde / ACPI: remove time from acpi_processor_cx structure
cpuidle / ACPI: remove usage from acpi_processor_cx structure
cpuidle / ACPI : remove latency_ticks from acpi_processor_cx structure
rtc-cmos: report wakeups from interrupt handler
PM / Sleep: Fix build warning in sysfs.c for CONFIG_PM_SLEEP unset
PM / Domains: Fix build warning for CONFIG_PM_RUNTIME unset
olpc-xo15-sci: Use struct dev_pm_ops for power management
PM / Domains: Replace plain integer with NULL pointer in domain.c file
PM / Domains: Add missing static storage class specifier in domain.c file
PM / crypto / ux500: Use struct dev_pm_ops for power management
PM / IPMI: Remove empty legacy PCI PM callbacks
tpm_nsc: Use struct dev_pm_ops for power management
tpm_tis: Use struct dev_pm_ops for power management
...
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/power/Kconfig | 4 | ||||
| -rw-r--r-- | kernel/power/hibernate.c | 42 | ||||
| -rw-r--r-- | kernel/power/main.c | 45 | ||||
| -rw-r--r-- | kernel/power/power.h | 3 | ||||
| -rw-r--r-- | kernel/power/suspend.c | 3 | ||||
| -rw-r--r-- | kernel/power/swap.c | 82 | ||||
| -rw-r--r-- | kernel/power/wakelock.c | 7 |
7 files changed, 157 insertions, 29 deletions
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 8f9b4eb974e0..a70518c9d82f 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
| @@ -175,7 +175,7 @@ config PM_TEST_SUSPEND | |||
| 175 | You probably want to have your system's RTC driver statically | 175 | You probably want to have your system's RTC driver statically |
| 176 | linked, ensuring that it's available when this test runs. | 176 | linked, ensuring that it's available when this test runs. |
| 177 | 177 | ||
| 178 | config CAN_PM_TRACE | 178 | config PM_SLEEP_DEBUG |
| 179 | def_bool y | 179 | def_bool y |
| 180 | depends on PM_DEBUG && PM_SLEEP | 180 | depends on PM_DEBUG && PM_SLEEP |
| 181 | 181 | ||
| @@ -196,7 +196,7 @@ config PM_TRACE | |||
| 196 | 196 | ||
| 197 | config PM_TRACE_RTC | 197 | config PM_TRACE_RTC |
| 198 | bool "Suspend/resume event tracing" | 198 | bool "Suspend/resume event tracing" |
| 199 | depends on CAN_PM_TRACE | 199 | depends on PM_SLEEP_DEBUG |
| 200 | depends on X86 | 200 | depends on X86 |
| 201 | select PM_TRACE | 201 | select PM_TRACE |
| 202 | ---help--- | 202 | ---help--- |
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 238025f5472e..b26f5f1e773e 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | * Copyright (c) 2003 Open Source Development Lab | 5 | * Copyright (c) 2003 Open Source Development Lab |
| 6 | * Copyright (c) 2004 Pavel Machek <pavel@ucw.cz> | 6 | * Copyright (c) 2004 Pavel Machek <pavel@ucw.cz> |
| 7 | * Copyright (c) 2009 Rafael J. Wysocki, Novell Inc. | 7 | * Copyright (c) 2009 Rafael J. Wysocki, Novell Inc. |
| 8 | * Copyright (C) 2012 Bojan Smojver <bojan@rexursive.com> | ||
| 8 | * | 9 | * |
| 9 | * This file is released under the GPLv2. | 10 | * This file is released under the GPLv2. |
| 10 | */ | 11 | */ |
| @@ -45,6 +46,9 @@ enum { | |||
| 45 | HIBERNATION_PLATFORM, | 46 | HIBERNATION_PLATFORM, |
| 46 | HIBERNATION_SHUTDOWN, | 47 | HIBERNATION_SHUTDOWN, |
| 47 | HIBERNATION_REBOOT, | 48 | HIBERNATION_REBOOT, |
| 49 | #ifdef CONFIG_SUSPEND | ||
| 50 | HIBERNATION_SUSPEND, | ||
| 51 | #endif | ||
| 48 | /* keep last */ | 52 | /* keep last */ |
| 49 | __HIBERNATION_AFTER_LAST | 53 | __HIBERNATION_AFTER_LAST |
| 50 | }; | 54 | }; |
| @@ -353,6 +357,7 @@ int hibernation_snapshot(int platform_mode) | |||
| 353 | } | 357 | } |
| 354 | 358 | ||
| 355 | suspend_console(); | 359 | suspend_console(); |
| 360 | ftrace_stop(); | ||
| 356 | pm_restrict_gfp_mask(); | 361 | pm_restrict_gfp_mask(); |
| 357 | 362 | ||
| 358 | error = dpm_suspend(PMSG_FREEZE); | 363 | error = dpm_suspend(PMSG_FREEZE); |
| @@ -378,6 +383,7 @@ int hibernation_snapshot(int platform_mode) | |||
| 378 | if (error || !in_suspend) | 383 | if (error || !in_suspend) |
| 379 | pm_restore_gfp_mask(); | 384 | pm_restore_gfp_mask(); |
| 380 | 385 | ||
| 386 | ftrace_start(); | ||
| 381 | resume_console(); | 387 | resume_console(); |
| 382 | dpm_complete(msg); | 388 | dpm_complete(msg); |
| 383 | 389 | ||
| @@ -480,6 +486,7 @@ int hibernation_restore(int platform_mode) | |||
| 480 | 486 | ||
| 481 | pm_prepare_console(); | 487 | pm_prepare_console(); |
| 482 | suspend_console(); | 488 | suspend_console(); |
| 489 | ftrace_stop(); | ||
| 483 | pm_restrict_gfp_mask(); | 490 | pm_restrict_gfp_mask(); |
| 484 | error = dpm_suspend_start(PMSG_QUIESCE); | 491 | error = dpm_suspend_start(PMSG_QUIESCE); |
| 485 | if (!error) { | 492 | if (!error) { |
| @@ -487,6 +494,7 @@ int hibernation_restore(int platform_mode) | |||
| 487 | dpm_resume_end(PMSG_RECOVER); | 494 | dpm_resume_end(PMSG_RECOVER); |
| 488 | } | 495 | } |
| 489 | pm_restore_gfp_mask(); | 496 | pm_restore_gfp_mask(); |
| 497 | ftrace_start(); | ||
| 490 | resume_console(); | 498 | resume_console(); |
| 491 | pm_restore_console(); | 499 | pm_restore_console(); |
| 492 | return error; | 500 | return error; |
| @@ -513,6 +521,7 @@ int hibernation_platform_enter(void) | |||
| 513 | 521 | ||
| 514 | entering_platform_hibernation = true; | 522 | entering_platform_hibernation = true; |
| 515 | suspend_console(); | 523 | suspend_console(); |
| 524 | ftrace_stop(); | ||
| 516 | error = dpm_suspend_start(PMSG_HIBERNATE); | 525 | error = dpm_suspend_start(PMSG_HIBERNATE); |
| 517 | if (error) { | 526 | if (error) { |
| 518 | if (hibernation_ops->recover) | 527 | if (hibernation_ops->recover) |
| @@ -556,6 +565,7 @@ int hibernation_platform_enter(void) | |||
| 556 | Resume_devices: | 565 | Resume_devices: |
| 557 | entering_platform_hibernation = false; | 566 | entering_platform_hibernation = false; |
| 558 | dpm_resume_end(PMSG_RESTORE); | 567 | dpm_resume_end(PMSG_RESTORE); |
| 568 | ftrace_start(); | ||
| 559 | resume_console(); | 569 | resume_console(); |
| 560 | 570 | ||
| 561 | Close: | 571 | Close: |
| @@ -573,6 +583,10 @@ int hibernation_platform_enter(void) | |||
| 573 | */ | 583 | */ |
| 574 | static void power_down(void) | 584 | static void power_down(void) |
| 575 | { | 585 | { |
| 586 | #ifdef CONFIG_SUSPEND | ||
| 587 | int error; | ||
| 588 | #endif | ||
| 589 | |||
| 576 | switch (hibernation_mode) { | 590 | switch (hibernation_mode) { |
| 577 | case HIBERNATION_REBOOT: | 591 | case HIBERNATION_REBOOT: |
| 578 | kernel_restart(NULL); | 592 | kernel_restart(NULL); |
| @@ -582,6 +596,25 @@ static void power_down(void) | |||
| 582 | case HIBERNATION_SHUTDOWN: | 596 | case HIBERNATION_SHUTDOWN: |
| 583 | kernel_power_off(); | 597 | kernel_power_off(); |
| 584 | break; | 598 | break; |
| 599 | #ifdef CONFIG_SUSPEND | ||
| 600 | case HIBERNATION_SUSPEND: | ||
| 601 | error = suspend_devices_and_enter(PM_SUSPEND_MEM); | ||
| 602 | if (error) { | ||
| 603 | if (hibernation_ops) | ||
| 604 | hibernation_mode = HIBERNATION_PLATFORM; | ||
| 605 | else | ||
| 606 | hibernation_mode = HIBERNATION_SHUTDOWN; | ||
| 607 | power_down(); | ||
| 608 | } | ||
| 609 | /* | ||
| 610 | * Restore swap signature. | ||
| 611 | */ | ||
| 612 | error = swsusp_unmark(); | ||
| 613 | if (error) | ||
| 614 | printk(KERN_ERR "PM: Swap will be unusable! " | ||
| 615 | "Try swapon -a.\n"); | ||
| 616 | return; | ||
| 617 | #endif | ||
| 585 | } | 618 | } |
| 586 | kernel_halt(); | 619 | kernel_halt(); |
| 587 | /* | 620 | /* |
| @@ -819,6 +852,9 @@ static const char * const hibernation_modes[] = { | |||
| 819 | [HIBERNATION_PLATFORM] = "platform", | 852 | [HIBERNATION_PLATFORM] = "platform", |
| 820 | [HIBERNATION_SHUTDOWN] = "shutdown", | 853 | [HIBERNATION_SHUTDOWN] = "shutdown", |
| 821 | [HIBERNATION_REBOOT] = "reboot", | 854 | [HIBERNATION_REBOOT] = "reboot", |
| 855 | #ifdef CONFIG_SUSPEND | ||
| 856 | [HIBERNATION_SUSPEND] = "suspend", | ||
| 857 | #endif | ||
| 822 | }; | 858 | }; |
| 823 | 859 | ||
| 824 | /* | 860 | /* |
| @@ -859,6 +895,9 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
| 859 | switch (i) { | 895 | switch (i) { |
| 860 | case HIBERNATION_SHUTDOWN: | 896 | case HIBERNATION_SHUTDOWN: |
| 861 | case HIBERNATION_REBOOT: | 897 | case HIBERNATION_REBOOT: |
| 898 | #ifdef CONFIG_SUSPEND | ||
| 899 | case HIBERNATION_SUSPEND: | ||
| 900 | #endif | ||
| 862 | break; | 901 | break; |
| 863 | case HIBERNATION_PLATFORM: | 902 | case HIBERNATION_PLATFORM: |
| 864 | if (hibernation_ops) | 903 | if (hibernation_ops) |
| @@ -899,6 +938,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, | |||
| 899 | switch (mode) { | 938 | switch (mode) { |
| 900 | case HIBERNATION_SHUTDOWN: | 939 | case HIBERNATION_SHUTDOWN: |
| 901 | case HIBERNATION_REBOOT: | 940 | case HIBERNATION_REBOOT: |
| 941 | #ifdef CONFIG_SUSPEND | ||
| 942 | case HIBERNATION_SUSPEND: | ||
| 943 | #endif | ||
| 902 | hibernation_mode = mode; | 944 | hibernation_mode = mode; |
| 903 | break; | 945 | break; |
| 904 | case HIBERNATION_PLATFORM: | 946 | case HIBERNATION_PLATFORM: |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 428f8a034e96..f458238109cc 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
| @@ -235,6 +235,47 @@ late_initcall(pm_debugfs_init); | |||
| 235 | 235 | ||
| 236 | #endif /* CONFIG_PM_SLEEP */ | 236 | #endif /* CONFIG_PM_SLEEP */ |
| 237 | 237 | ||
| 238 | #ifdef CONFIG_PM_SLEEP_DEBUG | ||
| 239 | /* | ||
| 240 | * pm_print_times: print time taken by devices to suspend and resume. | ||
| 241 | * | ||
| 242 | * show() returns whether printing of suspend and resume times is enabled. | ||
| 243 | * store() accepts 0 or 1. 0 disables printing and 1 enables it. | ||
| 244 | */ | ||
| 245 | bool pm_print_times_enabled; | ||
| 246 | |||
| 247 | static ssize_t pm_print_times_show(struct kobject *kobj, | ||
| 248 | struct kobj_attribute *attr, char *buf) | ||
| 249 | { | ||
| 250 | return sprintf(buf, "%d\n", pm_print_times_enabled); | ||
| 251 | } | ||
| 252 | |||
| 253 | static ssize_t pm_print_times_store(struct kobject *kobj, | ||
| 254 | struct kobj_attribute *attr, | ||
| 255 | const char *buf, size_t n) | ||
| 256 | { | ||
| 257 | unsigned long val; | ||
| 258 | |||
| 259 | if (kstrtoul(buf, 10, &val)) | ||
| 260 | return -EINVAL; | ||
| 261 | |||
| 262 | if (val > 1) | ||
| 263 | return -EINVAL; | ||
| 264 | |||
| 265 | pm_print_times_enabled = !!val; | ||
| 266 | return n; | ||
| 267 | } | ||
| 268 | |||
| 269 | power_attr(pm_print_times); | ||
| 270 | |||
| 271 | static inline void pm_print_times_init(void) | ||
| 272 | { | ||
| 273 | pm_print_times_enabled = !!initcall_debug; | ||
| 274 | } | ||
| 275 | #else /* !CONFIG_PP_SLEEP_DEBUG */ | ||
| 276 | static inline void pm_print_times_init(void) {} | ||
| 277 | #endif /* CONFIG_PM_SLEEP_DEBUG */ | ||
| 278 | |||
| 238 | struct kobject *power_kobj; | 279 | struct kobject *power_kobj; |
| 239 | 280 | ||
| 240 | /** | 281 | /** |
| @@ -531,6 +572,9 @@ static struct attribute * g[] = { | |||
| 531 | #ifdef CONFIG_PM_DEBUG | 572 | #ifdef CONFIG_PM_DEBUG |
| 532 | &pm_test_attr.attr, | 573 | &pm_test_attr.attr, |
| 533 | #endif | 574 | #endif |
| 575 | #ifdef CONFIG_PM_SLEEP_DEBUG | ||
| 576 | &pm_print_times_attr.attr, | ||
| 577 | #endif | ||
| 534 | #endif | 578 | #endif |
| 535 | NULL, | 579 | NULL, |
| 536 | }; | 580 | }; |
| @@ -566,6 +610,7 @@ static int __init pm_init(void) | |||
| 566 | error = sysfs_create_group(power_kobj, &attr_group); | 610 | error = sysfs_create_group(power_kobj, &attr_group); |
| 567 | if (error) | 611 | if (error) |
| 568 | return error; | 612 | return error; |
| 613 | pm_print_times_init(); | ||
| 569 | return pm_autosleep_init(); | 614 | return pm_autosleep_init(); |
| 570 | } | 615 | } |
| 571 | 616 | ||
diff --git a/kernel/power/power.h b/kernel/power/power.h index b0bd4beaebfe..7d4b7ffb3c1d 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
| @@ -156,6 +156,9 @@ extern void swsusp_free(void); | |||
| 156 | extern int swsusp_read(unsigned int *flags_p); | 156 | extern int swsusp_read(unsigned int *flags_p); |
| 157 | extern int swsusp_write(unsigned int flags); | 157 | extern int swsusp_write(unsigned int flags); |
| 158 | extern void swsusp_close(fmode_t); | 158 | extern void swsusp_close(fmode_t); |
| 159 | #ifdef CONFIG_SUSPEND | ||
| 160 | extern int swsusp_unmark(void); | ||
| 161 | #endif | ||
| 159 | 162 | ||
| 160 | /* kernel/power/block_io.c */ | 163 | /* kernel/power/block_io.c */ |
| 161 | extern struct block_device *hib_resume_bdev; | 164 | extern struct block_device *hib_resume_bdev; |
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 396d262b8fd0..c8b7446b27df 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/export.h> | 24 | #include <linux/export.h> |
| 25 | #include <linux/suspend.h> | 25 | #include <linux/suspend.h> |
| 26 | #include <linux/syscore_ops.h> | 26 | #include <linux/syscore_ops.h> |
| 27 | #include <linux/ftrace.h> | ||
| 27 | #include <trace/events/power.h> | 28 | #include <trace/events/power.h> |
| 28 | 29 | ||
| 29 | #include "power.h" | 30 | #include "power.h" |
| @@ -212,6 +213,7 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
| 212 | goto Close; | 213 | goto Close; |
| 213 | } | 214 | } |
| 214 | suspend_console(); | 215 | suspend_console(); |
| 216 | ftrace_stop(); | ||
| 215 | suspend_test_start(); | 217 | suspend_test_start(); |
| 216 | error = dpm_suspend_start(PMSG_SUSPEND); | 218 | error = dpm_suspend_start(PMSG_SUSPEND); |
| 217 | if (error) { | 219 | if (error) { |
| @@ -231,6 +233,7 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
| 231 | suspend_test_start(); | 233 | suspend_test_start(); |
| 232 | dpm_resume_end(PMSG_RESUME); | 234 | dpm_resume_end(PMSG_RESUME); |
| 233 | suspend_test_finish("resume devices"); | 235 | suspend_test_finish("resume devices"); |
| 236 | ftrace_start(); | ||
| 234 | resume_console(); | 237 | resume_console(); |
| 235 | Close: | 238 | Close: |
| 236 | if (suspend_ops->end) | 239 | if (suspend_ops->end) |
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 11e22c068e8b..3c9d764eb0d8 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
| @@ -448,9 +448,9 @@ static int save_image(struct swap_map_handle *handle, | |||
| 448 | struct timeval start; | 448 | struct timeval start; |
| 449 | struct timeval stop; | 449 | struct timeval stop; |
| 450 | 450 | ||
| 451 | printk(KERN_INFO "PM: Saving image data pages (%u pages) ... ", | 451 | printk(KERN_INFO "PM: Saving image data pages (%u pages)...\n", |
| 452 | nr_to_write); | 452 | nr_to_write); |
| 453 | m = nr_to_write / 100; | 453 | m = nr_to_write / 10; |
| 454 | if (!m) | 454 | if (!m) |
| 455 | m = 1; | 455 | m = 1; |
| 456 | nr_pages = 0; | 456 | nr_pages = 0; |
| @@ -464,7 +464,8 @@ static int save_image(struct swap_map_handle *handle, | |||
| 464 | if (ret) | 464 | if (ret) |
| 465 | break; | 465 | break; |
| 466 | if (!(nr_pages % m)) | 466 | if (!(nr_pages % m)) |
| 467 | printk(KERN_CONT "\b\b\b\b%3d%%", nr_pages / m); | 467 | printk(KERN_INFO "PM: Image saving progress: %3d%%\n", |
| 468 | nr_pages / m * 10); | ||
| 468 | nr_pages++; | 469 | nr_pages++; |
| 469 | } | 470 | } |
| 470 | err2 = hib_wait_on_bio_chain(&bio); | 471 | err2 = hib_wait_on_bio_chain(&bio); |
| @@ -472,9 +473,7 @@ static int save_image(struct swap_map_handle *handle, | |||
| 472 | if (!ret) | 473 | if (!ret) |
| 473 | ret = err2; | 474 | ret = err2; |
| 474 | if (!ret) | 475 | if (!ret) |
| 475 | printk(KERN_CONT "\b\b\b\bdone\n"); | 476 | printk(KERN_INFO "PM: Image saving done.\n"); |
| 476 | else | ||
| 477 | printk(KERN_CONT "\n"); | ||
| 478 | swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); | 477 | swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); |
| 479 | return ret; | 478 | return ret; |
| 480 | } | 479 | } |
| @@ -668,9 +667,9 @@ static int save_image_lzo(struct swap_map_handle *handle, | |||
| 668 | 667 | ||
| 669 | printk(KERN_INFO | 668 | printk(KERN_INFO |
| 670 | "PM: Using %u thread(s) for compression.\n" | 669 | "PM: Using %u thread(s) for compression.\n" |
| 671 | "PM: Compressing and saving image data (%u pages) ... ", | 670 | "PM: Compressing and saving image data (%u pages)...\n", |
| 672 | nr_threads, nr_to_write); | 671 | nr_threads, nr_to_write); |
| 673 | m = nr_to_write / 100; | 672 | m = nr_to_write / 10; |
| 674 | if (!m) | 673 | if (!m) |
| 675 | m = 1; | 674 | m = 1; |
| 676 | nr_pages = 0; | 675 | nr_pages = 0; |
| @@ -690,8 +689,10 @@ static int save_image_lzo(struct swap_map_handle *handle, | |||
| 690 | data_of(*snapshot), PAGE_SIZE); | 689 | data_of(*snapshot), PAGE_SIZE); |
| 691 | 690 | ||
| 692 | if (!(nr_pages % m)) | 691 | if (!(nr_pages % m)) |
| 693 | printk(KERN_CONT "\b\b\b\b%3d%%", | 692 | printk(KERN_INFO |
| 694 | nr_pages / m); | 693 | "PM: Image saving progress: " |
| 694 | "%3d%%\n", | ||
| 695 | nr_pages / m * 10); | ||
| 695 | nr_pages++; | 696 | nr_pages++; |
| 696 | } | 697 | } |
| 697 | if (!off) | 698 | if (!off) |
| @@ -761,11 +762,8 @@ out_finish: | |||
| 761 | do_gettimeofday(&stop); | 762 | do_gettimeofday(&stop); |
| 762 | if (!ret) | 763 | if (!ret) |
| 763 | ret = err2; | 764 | ret = err2; |
| 764 | if (!ret) { | 765 | if (!ret) |
| 765 | printk(KERN_CONT "\b\b\b\bdone\n"); | 766 | printk(KERN_INFO "PM: Image saving done.\n"); |
| 766 | } else { | ||
| 767 | printk(KERN_CONT "\n"); | ||
| 768 | } | ||
| 769 | swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); | 767 | swsusp_show_speed(&start, &stop, nr_to_write, "Wrote"); |
| 770 | out_clean: | 768 | out_clean: |
| 771 | if (crc) { | 769 | if (crc) { |
| @@ -973,9 +971,9 @@ static int load_image(struct swap_map_handle *handle, | |||
| 973 | int err2; | 971 | int err2; |
| 974 | unsigned nr_pages; | 972 | unsigned nr_pages; |
| 975 | 973 | ||
| 976 | printk(KERN_INFO "PM: Loading image data pages (%u pages) ... ", | 974 | printk(KERN_INFO "PM: Loading image data pages (%u pages)...\n", |
| 977 | nr_to_read); | 975 | nr_to_read); |
| 978 | m = nr_to_read / 100; | 976 | m = nr_to_read / 10; |
| 979 | if (!m) | 977 | if (!m) |
| 980 | m = 1; | 978 | m = 1; |
| 981 | nr_pages = 0; | 979 | nr_pages = 0; |
| @@ -993,7 +991,8 @@ static int load_image(struct swap_map_handle *handle, | |||
| 993 | if (ret) | 991 | if (ret) |
| 994 | break; | 992 | break; |
| 995 | if (!(nr_pages % m)) | 993 | if (!(nr_pages % m)) |
| 996 | printk("\b\b\b\b%3d%%", nr_pages / m); | 994 | printk(KERN_INFO "PM: Image loading progress: %3d%%\n", |
| 995 | nr_pages / m * 10); | ||
| 997 | nr_pages++; | 996 | nr_pages++; |
| 998 | } | 997 | } |
| 999 | err2 = hib_wait_on_bio_chain(&bio); | 998 | err2 = hib_wait_on_bio_chain(&bio); |
| @@ -1001,12 +1000,11 @@ static int load_image(struct swap_map_handle *handle, | |||
| 1001 | if (!ret) | 1000 | if (!ret) |
| 1002 | ret = err2; | 1001 | ret = err2; |
| 1003 | if (!ret) { | 1002 | if (!ret) { |
| 1004 | printk("\b\b\b\bdone\n"); | 1003 | printk(KERN_INFO "PM: Image loading done.\n"); |
| 1005 | snapshot_write_finalize(snapshot); | 1004 | snapshot_write_finalize(snapshot); |
| 1006 | if (!snapshot_image_loaded(snapshot)) | 1005 | if (!snapshot_image_loaded(snapshot)) |
| 1007 | ret = -ENODATA; | 1006 | ret = -ENODATA; |
| 1008 | } else | 1007 | } |
| 1009 | printk("\n"); | ||
| 1010 | swsusp_show_speed(&start, &stop, nr_to_read, "Read"); | 1008 | swsusp_show_speed(&start, &stop, nr_to_read, "Read"); |
| 1011 | return ret; | 1009 | return ret; |
| 1012 | } | 1010 | } |
| @@ -1185,9 +1183,9 @@ static int load_image_lzo(struct swap_map_handle *handle, | |||
| 1185 | 1183 | ||
| 1186 | printk(KERN_INFO | 1184 | printk(KERN_INFO |
| 1187 | "PM: Using %u thread(s) for decompression.\n" | 1185 | "PM: Using %u thread(s) for decompression.\n" |
| 1188 | "PM: Loading and decompressing image data (%u pages) ... ", | 1186 | "PM: Loading and decompressing image data (%u pages)...\n", |
| 1189 | nr_threads, nr_to_read); | 1187 | nr_threads, nr_to_read); |
| 1190 | m = nr_to_read / 100; | 1188 | m = nr_to_read / 10; |
| 1191 | if (!m) | 1189 | if (!m) |
| 1192 | m = 1; | 1190 | m = 1; |
| 1193 | nr_pages = 0; | 1191 | nr_pages = 0; |
| @@ -1319,7 +1317,10 @@ static int load_image_lzo(struct swap_map_handle *handle, | |||
| 1319 | data[thr].unc + off, PAGE_SIZE); | 1317 | data[thr].unc + off, PAGE_SIZE); |
| 1320 | 1318 | ||
| 1321 | if (!(nr_pages % m)) | 1319 | if (!(nr_pages % m)) |
| 1322 | printk("\b\b\b\b%3d%%", nr_pages / m); | 1320 | printk(KERN_INFO |
| 1321 | "PM: Image loading progress: " | ||
| 1322 | "%3d%%\n", | ||
| 1323 | nr_pages / m * 10); | ||
| 1323 | nr_pages++; | 1324 | nr_pages++; |
| 1324 | 1325 | ||
| 1325 | ret = snapshot_write_next(snapshot); | 1326 | ret = snapshot_write_next(snapshot); |
| @@ -1344,7 +1345,7 @@ out_finish: | |||
| 1344 | } | 1345 | } |
| 1345 | do_gettimeofday(&stop); | 1346 | do_gettimeofday(&stop); |
| 1346 | if (!ret) { | 1347 | if (!ret) { |
| 1347 | printk("\b\b\b\bdone\n"); | 1348 | printk(KERN_INFO "PM: Image loading done.\n"); |
| 1348 | snapshot_write_finalize(snapshot); | 1349 | snapshot_write_finalize(snapshot); |
| 1349 | if (!snapshot_image_loaded(snapshot)) | 1350 | if (!snapshot_image_loaded(snapshot)) |
| 1350 | ret = -ENODATA; | 1351 | ret = -ENODATA; |
| @@ -1357,8 +1358,7 @@ out_finish: | |||
| 1357 | } | 1358 | } |
| 1358 | } | 1359 | } |
| 1359 | } | 1360 | } |
| 1360 | } else | 1361 | } |
| 1361 | printk("\n"); | ||
| 1362 | swsusp_show_speed(&start, &stop, nr_to_read, "Read"); | 1362 | swsusp_show_speed(&start, &stop, nr_to_read, "Read"); |
| 1363 | out_clean: | 1363 | out_clean: |
| 1364 | for (i = 0; i < ring_size; i++) | 1364 | for (i = 0; i < ring_size; i++) |
| @@ -1472,6 +1472,34 @@ void swsusp_close(fmode_t mode) | |||
| 1472 | blkdev_put(hib_resume_bdev, mode); | 1472 | blkdev_put(hib_resume_bdev, mode); |
| 1473 | } | 1473 | } |
| 1474 | 1474 | ||
| 1475 | /** | ||
| 1476 | * swsusp_unmark - Unmark swsusp signature in the resume device | ||
| 1477 | */ | ||
| 1478 | |||
| 1479 | #ifdef CONFIG_SUSPEND | ||
| 1480 | int swsusp_unmark(void) | ||
| 1481 | { | ||
| 1482 | int error; | ||
| 1483 | |||
| 1484 | hib_bio_read_page(swsusp_resume_block, swsusp_header, NULL); | ||
| 1485 | if (!memcmp(HIBERNATE_SIG,swsusp_header->sig, 10)) { | ||
| 1486 | memcpy(swsusp_header->sig,swsusp_header->orig_sig, 10); | ||
| 1487 | error = hib_bio_write_page(swsusp_resume_block, | ||
| 1488 | swsusp_header, NULL); | ||
| 1489 | } else { | ||
| 1490 | printk(KERN_ERR "PM: Cannot find swsusp signature!\n"); | ||
| 1491 | error = -ENODEV; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | /* | ||
| 1495 | * We just returned from suspend, we don't need the image any more. | ||
| 1496 | */ | ||
| 1497 | free_all_swap_pages(root_swap); | ||
| 1498 | |||
| 1499 | return error; | ||
| 1500 | } | ||
| 1501 | #endif | ||
| 1502 | |||
| 1475 | static int swsusp_header_init(void) | 1503 | static int swsusp_header_init(void) |
| 1476 | { | 1504 | { |
| 1477 | swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL); | 1505 | swsusp_header = (struct swsusp_header*) __get_free_page(GFP_KERNEL); |
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c index c8fba3380076..8f50de394d22 100644 --- a/kernel/power/wakelock.c +++ b/kernel/power/wakelock.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * manipulate wakelocks on Android. | 9 | * manipulate wakelocks on Android. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/capability.h> | ||
| 12 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
| 13 | #include <linux/device.h> | 14 | #include <linux/device.h> |
| 14 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| @@ -188,6 +189,9 @@ int pm_wake_lock(const char *buf) | |||
| 188 | size_t len; | 189 | size_t len; |
| 189 | int ret = 0; | 190 | int ret = 0; |
| 190 | 191 | ||
| 192 | if (!capable(CAP_BLOCK_SUSPEND)) | ||
| 193 | return -EPERM; | ||
| 194 | |||
| 191 | while (*str && !isspace(*str)) | 195 | while (*str && !isspace(*str)) |
| 192 | str++; | 196 | str++; |
| 193 | 197 | ||
| @@ -231,6 +235,9 @@ int pm_wake_unlock(const char *buf) | |||
| 231 | size_t len; | 235 | size_t len; |
| 232 | int ret = 0; | 236 | int ret = 0; |
| 233 | 237 | ||
| 238 | if (!capable(CAP_BLOCK_SUSPEND)) | ||
| 239 | return -EPERM; | ||
| 240 | |||
| 234 | len = strlen(buf); | 241 | len = strlen(buf); |
| 235 | if (!len) | 242 | if (!len) |
| 236 | return -EINVAL; | 243 | return -EINVAL; |
