diff options
Diffstat (limited to 'drivers/base/power/sysfs.c')
-rw-r--r-- | drivers/base/power/sysfs.c | 100 |
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 | ||
43 | static const char enabled[] = "enabled"; | 77 | static const char enabled[] = "enabled"; |
44 | static const char disabled[] = "disabled"; | 78 | static const char disabled[] = "disabled"; |
45 | 79 | ||
80 | #ifdef CONFIG_PM_RUNTIME | ||
81 | static const char ctrl_auto[] = "auto"; | ||
82 | static const char ctrl_on[] = "on"; | ||
83 | |||
84 | static 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 | |||
91 | static 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 | |||
109 | static DEVICE_ATTR(control, 0644, control_show, control_store); | ||
110 | #endif | ||
111 | |||
46 | static ssize_t | 112 | static ssize_t |
47 | wake_show(struct device * dev, struct device_attribute *attr, char * buf) | 113 | wake_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 | ||
78 | static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); | 144 | static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); |
79 | 145 | ||
146 | #ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG | ||
147 | static 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 | |||
154 | static 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 | |||
172 | static DEVICE_ATTR(async, 0644, async_show, async_store); | ||
173 | #endif /* CONFIG_PM_SLEEP_ADVANCED_DEBUG */ | ||
80 | 174 | ||
81 | static struct attribute * power_attrs[] = { | 175 | static 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 | }; |
85 | static struct attribute_group pm_attr_group = { | 185 | static struct attribute_group pm_attr_group = { |