aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/sysfs.c')
-rw-r--r--drivers/base/power/sysfs.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 596aeecfdffe..86fd9373447e 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -4,9 +4,25 @@
4 4
5#include <linux/device.h> 5#include <linux/device.h>
6#include <linux/string.h> 6#include <linux/string.h>
7#include <linux/pm_runtime.h>
7#include "power.h" 8#include "power.h"
8 9
9/* 10/*
11 * control - Report/change current runtime PM setting of the device
12 *
13 * Runtime power management of a device can be blocked with the help of
14 * this attribute. All devices have one of the following two values for
15 * the power/control file:
16 *
17 * + "auto\n" to allow the device to be power managed at run time;
18 * + "on\n" to prevent the device from being power managed at run time;
19 *
20 * The default for all devices is "auto", which means that devices may be
21 * subject to automatic power management, depending on their drivers.
22 * Changing this attribute to "on" prevents the driver from power managing
23 * the device at run time. Doing that while the device is suspended causes
24 * it to be woken up.
25 *
10 * wakeup - Report/change current wakeup option for device 26 * wakeup - Report/change current wakeup option for device
11 * 27 *
12 * Some devices support "wakeup" events, which are hardware signals 28 * Some devices support "wakeup" events, which are hardware signals
@@ -38,11 +54,61 @@
38 * wakeup events internally (unless they are disabled), keeping 54 * wakeup events internally (unless they are disabled), keeping
39 * their hardware in low power modes whenever they're unused. This 55 * their hardware in low power modes whenever they're unused. This
40 * saves runtime power, without requiring system-wide sleep states. 56 * saves runtime power, without requiring system-wide sleep states.
57 *
58 * async - Report/change current async suspend setting for the device
59 *
60 * Asynchronous suspend and resume of the device during system-wide power
61 * state transitions can be enabled by writing "enabled" to this file.
62 * Analogously, if "disabled" is written to this file, the device will be
63 * suspended and resumed synchronously.
64 *
65 * All devices have one of the following two values for power/async:
66 *
67 * + "enabled\n" to permit the asynchronous suspend/resume of the device;
68 * + "disabled\n" to forbid it;
69 *
70 * NOTE: It generally is unsafe to permit the asynchronous suspend/resume
71 * of a device unless it is certain that all of the PM dependencies of the
72 * device are known to the PM core. However, for some devices this
73 * attribute is set to "enabled" by bus type code or device drivers and in
74 * that cases it should be safe to leave the default value.
41 */ 75 */
42 76
43static const char enabled[] = "enabled"; 77static const char enabled[] = "enabled";
44static const char disabled[] = "disabled"; 78static const char disabled[] = "disabled";
45 79
80#ifdef CONFIG_PM_RUNTIME
81static const char ctrl_auto[] = "auto";
82static const char ctrl_on[] = "on";
83
84static ssize_t control_show(struct device *dev, struct device_attribute *attr,
85 char *buf)
86{
87 return sprintf(buf, "%s\n",
88 dev->power.runtime_auto ? ctrl_auto : ctrl_on);
89}
90
91static ssize_t control_store(struct device * dev, struct device_attribute *attr,
92 const char * buf, size_t n)
93{
94 char *cp;
95 int len = n;
96
97 cp = memchr(buf, '\n', n);
98 if (cp)
99 len = cp - buf;
100 if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0)
101 pm_runtime_allow(dev);
102 else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0)
103 pm_runtime_forbid(dev);
104 else
105 return -EINVAL;
106 return n;
107}
108
109static DEVICE_ATTR(control, 0644, control_show, control_store);
110#endif
111
46static ssize_t 112static ssize_t
47wake_show(struct device * dev, struct device_attribute *attr, char * buf) 113wake_show(struct device * dev, struct device_attribute *attr, char * buf)
48{ 114{
@@ -77,9 +143,43 @@ wake_store(struct device * dev, struct device_attribute *attr,
77 143
78static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); 144static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
79 145
146#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
147static ssize_t async_show(struct device *dev, struct device_attribute *attr,
148 char *buf)
149{
150 return sprintf(buf, "%s\n",
151 device_async_suspend_enabled(dev) ? enabled : disabled);
152}
153
154static ssize_t async_store(struct device *dev, struct device_attribute *attr,
155 const char *buf, size_t n)
156{
157 char *cp;
158 int len = n;
159
160 cp = memchr(buf, '\n', n);
161 if (cp)
162 len = cp - buf;
163 if (len == sizeof enabled - 1 && strncmp(buf, enabled, len) == 0)
164 device_enable_async_suspend(dev);
165 else if (len == sizeof disabled - 1 && strncmp(buf, disabled, len) == 0)
166 device_disable_async_suspend(dev);
167 else
168 return -EINVAL;
169 return n;
170}
171
172static DEVICE_ATTR(async, 0644, async_show, async_store);
173#endif /* CONFIG_PM_SLEEP_ADVANCED_DEBUG */
80 174
81static struct attribute * power_attrs[] = { 175static struct attribute * power_attrs[] = {
176#ifdef CONFIG_PM_RUNTIME
177 &dev_attr_control.attr,
178#endif
82 &dev_attr_wakeup.attr, 179 &dev_attr_wakeup.attr,
180#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
181 &dev_attr_async.attr,
182#endif
83 NULL, 183 NULL,
84}; 184};
85static struct attribute_group pm_attr_group = { 185static struct attribute_group pm_attr_group = {