Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+41 -1
+12
Documentation/ABI/testing/sysfs-devices-resource_in_use
··· 1 + What: /sys/devices/.../resource_in_use 2 + Date: January 2013 3 + Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com> 4 + Description: 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.
+25 -1
drivers/acpi/power.c
··· 87 87 Power Resource Management 88 88 -------------------------------------------------------------------------- */ 89 89 90 + static inline 91 + struct acpi_power_resource *to_power_resource(struct acpi_device *device) 92 + { 93 + return container_of(device, struct acpi_power_resource, device); 94 + } 95 + 90 96 static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle) 91 97 { 92 98 struct acpi_device *device; ··· 100 94 if (acpi_bus_get_device(handle, &device)) 101 95 return NULL; 102 96 103 - return container_of(device, struct acpi_power_resource, device); 97 + return to_power_resource(device); 104 98 } 105 99 106 100 static int acpi_power_resources_list_add(acpi_handle handle, ··· 684 678 kfree(resource); 685 679 } 686 680 681 + static ssize_t acpi_power_in_use_show(struct device *dev, 682 + struct device_attribute *attr, 683 + char *buf) { 684 + struct acpi_power_resource *resource; 685 + 686 + resource = to_power_resource(to_acpi_device(dev)); 687 + return sprintf(buf, "%u\n", !!resource->ref_count); 688 + } 689 + static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL); 690 + 691 + static void acpi_power_sysfs_remove(struct acpi_device *device) 692 + { 693 + device_remove_file(&device->dev, &dev_attr_resource_in_use); 694 + } 695 + 687 696 int acpi_add_power_resource(acpi_handle handle) 688 697 { 689 698 struct acpi_power_resource *resource; ··· 745 724 result = acpi_device_add(device, acpi_release_power_resource); 746 725 if (result) 747 726 goto err; 727 + 728 + if (!device_create_file(&device->dev, &dev_attr_resource_in_use)) 729 + device->remove = acpi_power_sysfs_remove; 748 730 749 731 mutex_lock(&power_resource_list_lock); 750 732 list_add(&resource->list_node, &acpi_power_resource_list);
+3
drivers/acpi/scan.c
··· 791 791 792 792 acpi_power_add_remove_device(device, false); 793 793 acpi_device_remove_files(device); 794 + if (device->remove) 795 + device->remove(device); 796 + 794 797 device_del(&device->dev); 795 798 /* 796 799 * Drop the reference counts of all power resources the device depends
+1
include/acpi/acpi_bus.h
··· 280 280 struct mutex physical_node_lock; 281 281 DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE); 282 282 struct list_head power_dependent; 283 + void (*remove)(struct acpi_device *); 283 284 }; 284 285 285 286 static inline void *acpi_driver_data(struct acpi_device *d)