aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-devices-power_resources_D013
-rw-r--r--Documentation/ABI/testing/sysfs-devices-power_resources_D114
-rw-r--r--Documentation/ABI/testing/sysfs-devices-power_resources_D214
-rw-r--r--Documentation/ABI/testing/sysfs-devices-power_resources_D3hot14
-rw-r--r--drivers/acpi/power.c104
5 files changed, 146 insertions, 13 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D0 b/Documentation/ABI/testing/sysfs-devices-power_resources_D0
new file mode 100644
index 000000000000..73b77a6be196
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-power_resources_D0
@@ -0,0 +1,13 @@
1What: /sys/devices/.../power_resources_D0/
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../power_resources_D0/ directory is only
6 present for device objects representing ACPI device nodes that
7 use ACPI power resources for power management.
8
9 If present, it contains symbolic links to device directories
10 representing ACPI power resources that need to be turned on for
11 the given device node to be in ACPI power state D0. The names
12 of the links are the same as the names of the directories they
13 point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D1 b/Documentation/ABI/testing/sysfs-devices-power_resources_D1
new file mode 100644
index 000000000000..30c20703fb8c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-power_resources_D1
@@ -0,0 +1,14 @@
1What: /sys/devices/.../power_resources_D1/
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../power_resources_D1/ directory is only
6 present for device objects representing ACPI device nodes that
7 use ACPI power resources for power management and support ACPI
8 power state D1.
9
10 If present, it contains symbolic links to device directories
11 representing ACPI power resources that need to be turned on for
12 the given device node to be in ACPI power state D1. The names
13 of the links are the same as the names of the directories they
14 point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D2 b/Documentation/ABI/testing/sysfs-devices-power_resources_D2
new file mode 100644
index 000000000000..fd9d84b421e1
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-power_resources_D2
@@ -0,0 +1,14 @@
1What: /sys/devices/.../power_resources_D2/
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../power_resources_D2/ directory is only
6 present for device objects representing ACPI device nodes that
7 use ACPI power resources for power management and support ACPI
8 power state D2.
9
10 If present, it contains symbolic links to device directories
11 representing ACPI power resources that need to be turned on for
12 the given device node to be in ACPI power state D2. The names
13 of the links are the same as the names of the directories they
14 point to.
diff --git a/Documentation/ABI/testing/sysfs-devices-power_resources_D3hot b/Documentation/ABI/testing/sysfs-devices-power_resources_D3hot
new file mode 100644
index 000000000000..3df32c20addf
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-power_resources_D3hot
@@ -0,0 +1,14 @@
1What: /sys/devices/.../power_resources_D3hot/
2Date: January 2013
3Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
4Description:
5 The /sys/devices/.../power_resources_D3hot/ directory is only
6 present for device objects representing ACPI device nodes that
7 use ACPI power resources for power management and support ACPI
8 power state D3hot.
9
10 If present, it contains symbolic links to device directories
11 representing ACPI power resources that need to be turned on for
12 the given device node to be in ACPI power state D3hot. The
13 names of the links are the same as the names of the directories
14 they point to.
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 946720a4db57..9466f56b938f 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -41,6 +41,7 @@
41#include <linux/types.h> 41#include <linux/types.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/pm_runtime.h> 43#include <linux/pm_runtime.h>
44#include <linux/sysfs.h>
44#include <acpi/acpi_bus.h> 45#include <acpi/acpi_bus.h>
45#include <acpi/acpi_drivers.h> 46#include <acpi/acpi_drivers.h>
46#include "sleep.h" 47#include "sleep.h"
@@ -417,24 +418,101 @@ static void acpi_power_remove_dependent(struct acpi_power_resource *resource,
417 } 418 }
418} 419}
419 420
420void acpi_power_add_remove_device(struct acpi_device *adev, bool add) 421static struct attribute *attrs[] = {
422 NULL,
423};
424
425static struct attribute_group attr_groups[] = {
426 [ACPI_STATE_D0] = {
427 .name = "power_resources_D0",
428 .attrs = attrs,
429 },
430 [ACPI_STATE_D1] = {
431 .name = "power_resources_D1",
432 .attrs = attrs,
433 },
434 [ACPI_STATE_D2] = {
435 .name = "power_resources_D2",
436 .attrs = attrs,
437 },
438 [ACPI_STATE_D3_HOT] = {
439 .name = "power_resources_D3hot",
440 .attrs = attrs,
441 },
442};
443
444static void acpi_power_hide_list(struct acpi_device *adev, int state)
445{
446 struct acpi_device_power_state *ps = &adev->power.states[state];
447 struct acpi_power_resource_entry *entry;
448
449 if (list_empty(&ps->resources))
450 return;
451
452 list_for_each_entry_reverse(entry, &ps->resources, node) {
453 struct acpi_device *res_dev = &entry->resource->device;
454
455 sysfs_remove_link_from_group(&adev->dev.kobj,
456 attr_groups[state].name,
457 dev_name(&res_dev->dev));
458 }
459 sysfs_remove_group(&adev->dev.kobj, &attr_groups[state]);
460}
461
462static void acpi_power_expose_list(struct acpi_device *adev, int state)
421{ 463{
422 if (adev->power.flags.power_resources) { 464 struct acpi_device_power_state *ps = &adev->power.states[state];
423 struct acpi_device_power_state *ps; 465 struct acpi_power_resource_entry *entry;
424 struct acpi_power_resource_entry *entry; 466 int ret;
425 467
426 ps = &adev->power.states[ACPI_STATE_D0]; 468 if (list_empty(&ps->resources))
427 list_for_each_entry(entry, &ps->resources, node) { 469 return;
428 struct acpi_power_resource *resource = entry->resource; 470
429 471 ret = sysfs_create_group(&adev->dev.kobj, &attr_groups[state]);
430 if (add) 472 if (ret)
431 acpi_power_add_dependent(resource, adev); 473 return;
432 else 474
433 acpi_power_remove_dependent(resource, adev); 475 list_for_each_entry(entry, &ps->resources, node) {
476 struct acpi_device *res_dev = &entry->resource->device;
477
478 ret = sysfs_add_link_to_group(&adev->dev.kobj,
479 attr_groups[state].name,
480 &res_dev->dev.kobj,
481 dev_name(&res_dev->dev));
482 if (ret) {
483 acpi_power_hide_list(adev, state);
484 break;
434 } 485 }
435 } 486 }
436} 487}
437 488
489void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
490{
491 struct acpi_device_power_state *ps;
492 struct acpi_power_resource_entry *entry;
493 int state;
494
495 if (!adev->power.flags.power_resources)
496 return;
497
498 ps = &adev->power.states[ACPI_STATE_D0];
499 list_for_each_entry(entry, &ps->resources, node) {
500 struct acpi_power_resource *resource = entry->resource;
501
502 if (add)
503 acpi_power_add_dependent(resource, adev);
504 else
505 acpi_power_remove_dependent(resource, adev);
506 }
507
508 for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++) {
509 if (add)
510 acpi_power_expose_list(adev, state);
511 else
512 acpi_power_hide_list(adev, state);
513 }
514}
515
438int acpi_power_min_system_level(struct list_head *list) 516int acpi_power_min_system_level(struct list_head *list)
439{ 517{
440 struct acpi_power_resource_entry *entry; 518 struct acpi_power_resource_entry *entry;