aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-24 06:49:59 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-24 06:49:59 -0500
commit836aedb1414d4724b2ec68dd19810960c593720c (patch)
tree4f826283e16638ba521f5d31b021d79166cfde99
parentcf860be639d86ed77af179c925085ae0721ae602 (diff)
ACPI / PM: Expose power states of ACPI devices to user space
Make it possible to retrieve the current power state of a device with ACPI power management from user space via sysfs by adding two new attributes, power_state and real_power_state, to the sysfs directory associated with the struct acpi_device object representing the device's ACPI node. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--Documentation/ABI/testing/sysfs-devices-power_state20
-rw-r--r--Documentation/ABI/testing/sysfs-devices-real_power_state23
-rw-r--r--drivers/acpi/scan.c49
3 files changed, 91 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-power_state b/Documentation/ABI/testing/sysfs-devices-power_state
new file mode 100644
index 000000000000..7ad9546748f0
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-power_state
@@ -0,0 +1,20 @@
1What: /sys/devices/.../power_state
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../power_state attribute is only present for
6 device objects representing ACPI device nodes that provide power
7 management methods.
8
9 If present, it contains a string representing the current ACPI
10 power state of the given device node. Its possible values,
11 "D0", "D1", "D2", "D3hot", and "D3cold", reflect the power state
12 names defined by the ACPI specification (ACPI 4 and above).
13
14 If the device node uses shared ACPI power resources, this state
15 determines a list of power resources required not to be turned
16 off. However, some power resources needed by the device node in
17 higher-power (lower-number) states may also be ON because of
18 some other devices using them at the moment.
19
20 This attribute is read-only.
diff --git a/Documentation/ABI/testing/sysfs-devices-real_power_state b/Documentation/ABI/testing/sysfs-devices-real_power_state
new file mode 100644
index 000000000000..8b3527c82a7d
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-real_power_state
@@ -0,0 +1,23 @@
1What: /sys/devices/.../real_power_state
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../real_power_state attribute is only present
6 for device objects representing ACPI device nodes that provide
7 power management methods and use ACPI power resources for power
8 management.
9
10 If present, it contains a string representing the real ACPI
11 power state of the given device node as returned by the _PSC
12 control method or inferred from the configuration of power
13 resources. Its possible values, "D0", "D1", "D2", "D3hot", and
14 "D3cold", reflect the power state names defined by the ACPI
15 specification (ACPI 4 and above).
16
17 In some situations the value of this attribute may be different
18 from the value of the /sys/devices/.../power_state attribute for
19 the same device object. If that happens, some shared power
20 resources used by the device node are only ON because of some
21 other devices using them at the moment.
22
23 This attribute is read-only.
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 8b3b18846c8c..9761d589f3f5 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -178,6 +178,32 @@ err_out:
178} 178}
179EXPORT_SYMBOL(acpi_bus_hot_remove_device); 179EXPORT_SYMBOL(acpi_bus_hot_remove_device);
180 180
181static ssize_t real_power_state_show(struct device *dev,
182 struct device_attribute *attr, char *buf)
183{
184 struct acpi_device *adev = to_acpi_device(dev);
185 int state;
186 int ret;
187
188 ret = acpi_device_get_power(adev, &state);
189 if (ret)
190 return ret;
191
192 return sprintf(buf, "%s\n", acpi_power_state_string(state));
193}
194
195static DEVICE_ATTR(real_power_state, 0444, real_power_state_show, NULL);
196
197static ssize_t power_state_show(struct device *dev,
198 struct device_attribute *attr, char *buf)
199{
200 struct acpi_device *adev = to_acpi_device(dev);
201
202 return sprintf(buf, "%s\n", acpi_power_state_string(adev->power.state));
203}
204
205static DEVICE_ATTR(power_state, 0444, power_state_show, NULL);
206
181static ssize_t 207static ssize_t
182acpi_eject_store(struct device *d, struct device_attribute *attr, 208acpi_eject_store(struct device *d, struct device_attribute *attr,
183 const char *buf, size_t count) 209 const char *buf, size_t count)
@@ -369,8 +395,22 @@ static int acpi_device_setup_files(struct acpi_device *dev)
369 * hot-removal function from userland. 395 * hot-removal function from userland.
370 */ 396 */
371 status = acpi_get_handle(dev->handle, "_EJ0", &temp); 397 status = acpi_get_handle(dev->handle, "_EJ0", &temp);
372 if (ACPI_SUCCESS(status)) 398 if (ACPI_SUCCESS(status)) {
373 result = device_create_file(&dev->dev, &dev_attr_eject); 399 result = device_create_file(&dev->dev, &dev_attr_eject);
400 if (result)
401 return result;
402 }
403
404 if (dev->flags.power_manageable) {
405 result = device_create_file(&dev->dev, &dev_attr_power_state);
406 if (result)
407 return result;
408
409 if (dev->power.flags.power_resources)
410 result = device_create_file(&dev->dev,
411 &dev_attr_real_power_state);
412 }
413
374end: 414end:
375 return result; 415 return result;
376} 416}
@@ -380,6 +420,13 @@ static void acpi_device_remove_files(struct acpi_device *dev)
380 acpi_status status; 420 acpi_status status;
381 acpi_handle temp; 421 acpi_handle temp;
382 422
423 if (dev->flags.power_manageable) {
424 device_remove_file(&dev->dev, &dev_attr_power_state);
425 if (dev->power.flags.power_resources)
426 device_remove_file(&dev->dev,
427 &dev_attr_real_power_state);
428 }
429
383 /* 430 /*
384 * If device has _STR, remove 'description' file 431 * If device has _STR, remove 'description' file
385 */ 432 */