aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt10
-rw-r--r--drivers/base/power/sysfs.c24
-rw-r--r--kernel/power/suspend.c2
-rw-r--r--kernel/power/suspend_test.c32
4 files changed, 50 insertions, 18 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 10d51c2f10d7..ccbab5653bb8 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -3303,11 +3303,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
3303 3303
3304 tdfx= [HW,DRM] 3304 tdfx= [HW,DRM]
3305 3305
3306 test_suspend= [SUSPEND] 3306 test_suspend= [SUSPEND][,N]
3307 Specify "mem" (for Suspend-to-RAM) or "standby" (for 3307 Specify "mem" (for Suspend-to-RAM) or "standby" (for
3308 standby suspend) as the system sleep state to briefly 3308 standby suspend) or "freeze" (for suspend type freeze)
3309 enter during system startup. The system is woken from 3309 as the system sleep state during system startup with
3310 this state using a wakeup-capable RTC alarm. 3310 the optional capability to repeat N number of times.
3311 The system is woken from this state using a
3312 wakeup-capable RTC alarm.
3311 3313
3312 thash_entries= [KNL,NET] 3314 thash_entries= [KNL,NET]
3313 Set number of hash buckets for TCP connection 3315 Set number of hash buckets for TCP connection
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 95b181d1ca6d..a9d26ed11bf4 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -92,9 +92,6 @@
92 * wakeup_count - Report the number of wakeup events related to the device 92 * wakeup_count - Report the number of wakeup events related to the device
93 */ 93 */
94 94
95static const char enabled[] = "enabled";
96static const char disabled[] = "disabled";
97
98const char power_group_name[] = "power"; 95const char power_group_name[] = "power";
99EXPORT_SYMBOL_GPL(power_group_name); 96EXPORT_SYMBOL_GPL(power_group_name);
100 97
@@ -336,11 +333,14 @@ static DEVICE_ATTR(pm_qos_remote_wakeup, 0644,
336#endif /* CONFIG_PM_RUNTIME */ 333#endif /* CONFIG_PM_RUNTIME */
337 334
338#ifdef CONFIG_PM_SLEEP 335#ifdef CONFIG_PM_SLEEP
336static const char _enabled[] = "enabled";
337static const char _disabled[] = "disabled";
338
339static ssize_t 339static ssize_t
340wake_show(struct device * dev, struct device_attribute *attr, char * buf) 340wake_show(struct device * dev, struct device_attribute *attr, char * buf)
341{ 341{
342 return sprintf(buf, "%s\n", device_can_wakeup(dev) 342 return sprintf(buf, "%s\n", device_can_wakeup(dev)
343 ? (device_may_wakeup(dev) ? enabled : disabled) 343 ? (device_may_wakeup(dev) ? _enabled : _disabled)
344 : ""); 344 : "");
345} 345}
346 346
@@ -357,11 +357,11 @@ wake_store(struct device * dev, struct device_attribute *attr,
357 cp = memchr(buf, '\n', n); 357 cp = memchr(buf, '\n', n);
358 if (cp) 358 if (cp)
359 len = cp - buf; 359 len = cp - buf;
360 if (len == sizeof enabled - 1 360 if (len == sizeof _enabled - 1
361 && strncmp(buf, enabled, sizeof enabled - 1) == 0) 361 && strncmp(buf, _enabled, sizeof _enabled - 1) == 0)
362 device_set_wakeup_enable(dev, 1); 362 device_set_wakeup_enable(dev, 1);
363 else if (len == sizeof disabled - 1 363 else if (len == sizeof _disabled - 1
364 && strncmp(buf, disabled, sizeof disabled - 1) == 0) 364 && strncmp(buf, _disabled, sizeof _disabled - 1) == 0)
365 device_set_wakeup_enable(dev, 0); 365 device_set_wakeup_enable(dev, 0);
366 else 366 else
367 return -EINVAL; 367 return -EINVAL;
@@ -570,7 +570,8 @@ static ssize_t async_show(struct device *dev, struct device_attribute *attr,
570 char *buf) 570 char *buf)
571{ 571{
572 return sprintf(buf, "%s\n", 572 return sprintf(buf, "%s\n",
573 device_async_suspend_enabled(dev) ? enabled : disabled); 573 device_async_suspend_enabled(dev) ?
574 _enabled : _disabled);
574} 575}
575 576
576static ssize_t async_store(struct device *dev, struct device_attribute *attr, 577static ssize_t async_store(struct device *dev, struct device_attribute *attr,
@@ -582,9 +583,10 @@ static ssize_t async_store(struct device *dev, struct device_attribute *attr,
582 cp = memchr(buf, '\n', n); 583 cp = memchr(buf, '\n', n);
583 if (cp) 584 if (cp)
584 len = cp - buf; 585 len = cp - buf;
585 if (len == sizeof enabled - 1 && strncmp(buf, enabled, len) == 0) 586 if (len == sizeof _enabled - 1 && strncmp(buf, _enabled, len) == 0)
586 device_enable_async_suspend(dev); 587 device_enable_async_suspend(dev);
587 else if (len == sizeof disabled - 1 && strncmp(buf, disabled, len) == 0) 588 else if (len == sizeof _disabled - 1 &&
589 strncmp(buf, _disabled, len) == 0)
588 device_disable_async_suspend(dev); 590 device_disable_async_suspend(dev);
589 else 591 else
590 return -EINVAL; 592 return -EINVAL;
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 18c62195660f..e837dd6783c6 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -361,7 +361,9 @@ int suspend_devices_and_enter(suspend_state_t state)
361 suspend_test_start(); 361 suspend_test_start();
362 dpm_resume_end(PMSG_RESUME); 362 dpm_resume_end(PMSG_RESUME);
363 suspend_test_finish("resume devices"); 363 suspend_test_finish("resume devices");
364 trace_suspend_resume(TPS("resume_console"), state, true);
364 resume_console(); 365 resume_console();
366 trace_suspend_resume(TPS("resume_console"), state, false);
365 367
366 Close: 368 Close:
367 platform_suspend_end(state); 369 platform_suspend_end(state);
diff --git a/kernel/power/suspend_test.c b/kernel/power/suspend_test.c
index bd91bc177c93..084452e34a12 100644
--- a/kernel/power/suspend_test.c
+++ b/kernel/power/suspend_test.c
@@ -22,6 +22,8 @@
22#define TEST_SUSPEND_SECONDS 10 22#define TEST_SUSPEND_SECONDS 10
23 23
24static unsigned long suspend_test_start_time; 24static unsigned long suspend_test_start_time;
25static u32 test_repeat_count_max = 1;
26static u32 test_repeat_count_current;
25 27
26void suspend_test_start(void) 28void suspend_test_start(void)
27{ 29{
@@ -74,6 +76,7 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
74 int status; 76 int status;
75 77
76 /* this may fail if the RTC hasn't been initialized */ 78 /* this may fail if the RTC hasn't been initialized */
79repeat:
77 status = rtc_read_time(rtc, &alm.time); 80 status = rtc_read_time(rtc, &alm.time);
78 if (status < 0) { 81 if (status < 0) {
79 printk(err_readtime, dev_name(&rtc->dev), status); 82 printk(err_readtime, dev_name(&rtc->dev), status);
@@ -100,10 +103,21 @@ static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state)
100 if (state == PM_SUSPEND_STANDBY) { 103 if (state == PM_SUSPEND_STANDBY) {
101 printk(info_test, pm_states[state]); 104 printk(info_test, pm_states[state]);
102 status = pm_suspend(state); 105 status = pm_suspend(state);
106 if (status < 0)
107 state = PM_SUSPEND_FREEZE;
103 } 108 }
109 if (state == PM_SUSPEND_FREEZE) {
110 printk(info_test, pm_states[state]);
111 status = pm_suspend(state);
112 }
113
104 if (status < 0) 114 if (status < 0)
105 printk(err_suspend, status); 115 printk(err_suspend, status);
106 116
117 test_repeat_count_current++;
118 if (test_repeat_count_current < test_repeat_count_max)
119 goto repeat;
120
107 /* Some platforms can't detect that the alarm triggered the 121 /* Some platforms can't detect that the alarm triggered the
108 * wakeup, or (accordingly) disable it after it afterwards. 122 * wakeup, or (accordingly) disable it after it afterwards.
109 * It's supposed to give oneshot behavior; cope. 123 * It's supposed to give oneshot behavior; cope.
@@ -137,16 +151,28 @@ static char warn_bad_state[] __initdata =
137static int __init setup_test_suspend(char *value) 151static int __init setup_test_suspend(char *value)
138{ 152{
139 int i; 153 int i;
154 char *repeat;
155 char *suspend_type;
140 156
141 /* "=mem" ==> "mem" */ 157 /* example : "=mem[,N]" ==> "mem[,N]" */
142 value++; 158 value++;
159 suspend_type = strsep(&value, ",");
160 if (!suspend_type)
161 return 0;
162
163 repeat = strsep(&value, ",");
164 if (repeat) {
165 if (kstrtou32(repeat, 0, &test_repeat_count_max))
166 return 0;
167 }
168
143 for (i = 0; pm_labels[i]; i++) 169 for (i = 0; pm_labels[i]; i++)
144 if (!strcmp(pm_labels[i], value)) { 170 if (!strcmp(pm_labels[i], suspend_type)) {
145 test_state_label = pm_labels[i]; 171 test_state_label = pm_labels[i];
146 return 0; 172 return 0;
147 } 173 }
148 174
149 printk(warn_bad_state, value); 175 printk(warn_bad_state, suspend_type);
150 return 0; 176 return 0;
151} 177}
152__setup("test_suspend", setup_test_suspend); 178__setup("test_suspend", setup_test_suspend);