aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-devices-resource_in_use12
-rw-r--r--drivers/acpi/power.c26
-rw-r--r--drivers/acpi/scan.c3
-rw-r--r--include/acpi/acpi_bus.h1
4 files changed, 41 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-resource_in_use b/Documentation/ABI/testing/sysfs-devices-resource_in_use
new file mode 100644
index 000000000000..b4a3bc5922a3
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-resource_in_use
@@ -0,0 +1,12 @@
1What: /sys/devices/.../resource_in_use
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../resource_in_use attribute is only present
6 for device objects representing ACPI power resources.
7
8 If present, it contains a number (0 or 1) representing the
9 current status of the given power resource (0 means that the
10 resource is not in use and therefore it has been turned off).
11
12 This attribute is read-only.
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);
87 Power Resource Management 87 Power Resource Management
88 -------------------------------------------------------------------------- */ 88 -------------------------------------------------------------------------- */
89 89
90static inline
91struct acpi_power_resource *to_power_resource(struct acpi_device *device)
92{
93 return container_of(device, struct acpi_power_resource, device);
94}
95
90static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle) 96static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
91{ 97{
92 struct acpi_device *device; 98 struct acpi_device *device;
@@ -94,7 +100,7 @@ static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle)
94 if (acpi_bus_get_device(handle, &device)) 100 if (acpi_bus_get_device(handle, &device))
95 return NULL; 101 return NULL;
96 102
97 return container_of(device, struct acpi_power_resource, device); 103 return to_power_resource(device);
98} 104}
99 105
100static int acpi_power_resources_list_add(acpi_handle handle, 106static int acpi_power_resources_list_add(acpi_handle handle,
@@ -678,6 +684,21 @@ static void acpi_release_power_resource(struct device *dev)
678 kfree(resource); 684 kfree(resource);
679} 685}
680 686
687static ssize_t acpi_power_in_use_show(struct device *dev,
688 struct device_attribute *attr,
689 char *buf) {
690 struct acpi_power_resource *resource;
691
692 resource = to_power_resource(to_acpi_device(dev));
693 return sprintf(buf, "%u\n", !!resource->ref_count);
694}
695static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL);
696
697static void acpi_power_sysfs_remove(struct acpi_device *device)
698{
699 device_remove_file(&device->dev, &dev_attr_resource_in_use);
700}
701
681int acpi_add_power_resource(acpi_handle handle) 702int acpi_add_power_resource(acpi_handle handle)
682{ 703{
683 struct acpi_power_resource *resource; 704 struct acpi_power_resource *resource;
@@ -725,6 +746,9 @@ int acpi_add_power_resource(acpi_handle handle)
725 if (result) 746 if (result)
726 goto err; 747 goto err;
727 748
749 if (!device_create_file(&device->dev, &dev_attr_resource_in_use))
750 device->remove = acpi_power_sysfs_remove;
751
728 mutex_lock(&power_resource_list_lock); 752 mutex_lock(&power_resource_list_lock);
729 list_add(&resource->list_node, &acpi_power_resource_list); 753 list_add(&resource->list_node, &acpi_power_resource_list);
730 mutex_unlock(&power_resource_list_lock); 754 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)
791 791
792 acpi_power_add_remove_device(device, false); 792 acpi_power_add_remove_device(device, false);
793 acpi_device_remove_files(device); 793 acpi_device_remove_files(device);
794 if (device->remove)
795 device->remove(device);
796
794 device_del(&device->dev); 797 device_del(&device->dev);
795 /* 798 /*
796 * Drop the reference counts of all power resources the device depends 799 * Drop the reference counts of all power resources the device depends
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index fca1b9cb27d9..aef56a9f4e70 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -280,6 +280,7 @@ struct acpi_device {
280 struct mutex physical_node_lock; 280 struct mutex physical_node_lock;
281 DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE); 281 DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
282 struct list_head power_dependent; 282 struct list_head power_dependent;
283 void (*remove)(struct acpi_device *);
283}; 284};
284 285
285static inline void *acpi_driver_data(struct acpi_device *d) 286static inline void *acpi_driver_data(struct acpi_device *d)