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/power | |
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/power')
-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; |