summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-24 12:50:09 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-24 12:50:09 +0100
commitb1c0f99bfb89cd9b42e3119ab822a8102fa87909 (patch)
tree4a6f07a25ca239bb579cc583c67b92ab451d40b7 /drivers
parentACPI / PM: Expose power states of ACPI devices to user space (diff)
downloadlinux-b1c0f99bfb89cd9b42e3119ab822a8102fa87909.tar.xz
linux-b1c0f99bfb89cd9b42e3119ab822a8102fa87909.zip
ACPI / PM: Expose current status of ACPI power resources
Since ACPI power resources are going to be used more extensively on new hardware platforms, it becomes necessary for user space (powertop in particular) to observe some properties of those resources for diagnostics purposes. For this reason, expose the current status of each ACPI power resource to user space via sysfs by adding a new resource_in_use attribute to the sysfs directory representing the given power resource. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/power.c26
-rw-r--r--drivers/acpi/scan.c3
2 files changed, 28 insertions, 1 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 3f16dd4db23e..946720a4db57 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -87,6 +87,12 @@ static DEFINE_MUTEX(power_resource_list_lock);
Power Resource Management
-------------------------------------------------------------------------- */
+static inline
+struct acpi_power_resource *to_power_resource(struct acpi_device *device)
+{
+ return container_of(device, struct acpi_power_resource, device);
+}
+
static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
{
struct acpi_device *device;
@@ -94,7 +100,7 @@ static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
if (acpi_bus_get_device(handle, &device))
return NULL;
- return container_of(device, struct acpi_power_resource, device);
+ return to_power_resource(device);
}
static int acpi_power_resources_list_add(acpi_handle handle,
@@ -678,6 +684,21 @@ static void acpi_release_power_resource(struct device *dev)
kfree(resource);
}
+static ssize_t acpi_power_in_use_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf) {
+ struct acpi_power_resource *resource;
+
+ resource = to_power_resource(to_acpi_device(dev));
+ return sprintf(buf, "%u\n", !!resource->ref_count);
+}
+static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL);
+
+static void acpi_power_sysfs_remove(struct acpi_device *device)
+{
+ device_remove_file(&device->dev, &dev_attr_resource_in_use);
+}
+
int acpi_add_power_resource(acpi_handle handle)
{
struct acpi_power_resource *resource;
@@ -725,6 +746,9 @@ int acpi_add_power_resource(acpi_handle handle)
if (result)
goto err;
+ if (!device_create_file(&device->dev, &dev_attr_resource_in_use))
+ device->remove = acpi_power_sysfs_remove;
+
mutex_lock(&power_resource_list_lock);
list_add(&resource->list_node, &acpi_power_resource_list);
mutex_unlock(&power_resource_list_lock);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9761d589f3f5..9801837876b7 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -791,6 +791,9 @@ static void acpi_device_unregister(struct acpi_device *device)
acpi_power_add_remove_device(device, false);
acpi_device_remove_files(device);
+ if (device->remove)
+ device->remove(device);
+
device_del(&device->dev);
/*
* Drop the reference counts of all power resources the device depends