blob: c011ff15632c8fe5eeb41d26be83ebd52809a5d9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * drivers/base/power/sysfs.c - sysfs entries for device PM
3 */
4
5#include <linux/device.h>
Tim Schmielau8c65b4a2005-11-07 00:59:43 -08006#include <linux/string.h>
Rafael J. Wysocki53823632010-01-23 22:02:51 +01007#include <linux/pm_runtime.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07008#include "power.h"
9
David Brownell0ac85242005-09-12 19:39:34 -070010/*
Rafael J. Wysocki53823632010-01-23 22:02:51 +010011 * 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 *
David Brownell0ac85242005-09-12 19:39:34 -070026 * wakeup - Report/change current wakeup option for device
27 *
28 * Some devices support "wakeup" events, which are hardware signals
29 * used to activate devices from suspended or low power states. Such
30 * devices have one of three values for the sysfs power/wakeup file:
31 *
32 * + "enabled\n" to issue the events;
33 * + "disabled\n" not to do so; or
34 * + "\n" for temporary or permanent inability to issue wakeup.
35 *
36 * (For example, unconfigured USB devices can't issue wakeups.)
37 *
38 * Familiar examples of devices that can issue wakeup events include
39 * keyboards and mice (both PS2 and USB styles), power buttons, modems,
40 * "Wake-On-LAN" Ethernet links, GPIO lines, and more. Some events
41 * will wake the entire system from a suspend state; others may just
42 * wake up the device (if the system as a whole is already active).
43 * Some wakeup events use normal IRQ lines; other use special out
44 * of band signaling.
45 *
46 * It is the responsibility of device drivers to enable (or disable)
47 * wakeup signaling as part of changing device power states, respecting
48 * the policy choices provided through the driver model.
49 *
50 * Devices may not be able to generate wakeup events from all power
51 * states. Also, the events may be ignored in some configurations;
52 * for example, they might need help from other devices that aren't
53 * active, or which may have wakeup disabled. Some drivers rely on
54 * wakeup events internally (unless they are disabled), keeping
55 * their hardware in low power modes whenever they're unused. This
56 * saves runtime power, without requiring system-wide sleep states.
57 */
58
59static const char enabled[] = "enabled";
60static const char disabled[] = "disabled";
61
Rafael J. Wysocki53823632010-01-23 22:02:51 +010062#ifdef CONFIG_PM_RUNTIME
63static const char ctrl_auto[] = "auto";
64static const char ctrl_on[] = "on";
65
66static ssize_t control_show(struct device *dev, struct device_attribute *attr,
67 char *buf)
68{
69 return sprintf(buf, "%s\n",
70 dev->power.runtime_auto ? ctrl_auto : ctrl_on);
71}
72
73static ssize_t control_store(struct device * dev, struct device_attribute *attr,
74 const char * buf, size_t n)
75{
76 char *cp;
77 int len = n;
78
79 cp = memchr(buf, '\n', n);
80 if (cp)
81 len = cp - buf;
82 if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0)
83 pm_runtime_allow(dev);
84 else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0)
85 pm_runtime_forbid(dev);
86 else
87 return -EINVAL;
88 return n;
89}
90
91static DEVICE_ATTR(control, 0644, control_show, control_store);
92#endif
93
David Brownell0ac85242005-09-12 19:39:34 -070094static ssize_t
95wake_show(struct device * dev, struct device_attribute *attr, char * buf)
96{
97 return sprintf(buf, "%s\n", device_can_wakeup(dev)
98 ? (device_may_wakeup(dev) ? enabled : disabled)
99 : "");
100}
101
102static ssize_t
103wake_store(struct device * dev, struct device_attribute *attr,
104 const char * buf, size_t n)
105{
106 char *cp;
107 int len = n;
108
109 if (!device_can_wakeup(dev))
110 return -EINVAL;
111
112 cp = memchr(buf, '\n', n);
113 if (cp)
114 len = cp - buf;
115 if (len == sizeof enabled - 1
116 && strncmp(buf, enabled, sizeof enabled - 1) == 0)
117 device_set_wakeup_enable(dev, 1);
118 else if (len == sizeof disabled - 1
119 && strncmp(buf, disabled, sizeof disabled - 1) == 0)
120 device_set_wakeup_enable(dev, 0);
121 else
122 return -EINVAL;
123 return n;
124}
125
126static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
127
128
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129static struct attribute * power_attrs[] = {
Rafael J. Wysocki53823632010-01-23 22:02:51 +0100130#ifdef CONFIG_PM_RUNTIME
131 &dev_attr_control.attr,
132#endif
David Brownell0ac85242005-09-12 19:39:34 -0700133 &dev_attr_wakeup.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 NULL,
135};
136static struct attribute_group pm_attr_group = {
137 .name = "power",
138 .attrs = power_attrs,
139};
140
141int dpm_sysfs_add(struct device * dev)
142{
143 return sysfs_create_group(&dev->kobj, &pm_attr_group);
144}
145
146void dpm_sysfs_remove(struct device * dev)
147{
148 sysfs_remove_group(&dev->kobj, &pm_attr_group);
149}