Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 350941
b: refs/heads/master
c: 18a3870
h: refs/heads/master
i:
  350939: 80119ce
v: v3
  • Loading branch information
Rafael J. Wysocki committed Jan 25, 2013
1 parent b9de314 commit 6aa0ab6
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0bb8f3d6ae621945e6fa2102aa894f72b76a023e
refs/heads/master: 18a387099b3e3fd901cc706f708b163aa45347b6
13 changes: 13 additions & 0 deletions trunk/Documentation/ABI/testing/sysfs-devices-power_resources_D0
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
What: /sys/devices/.../power_resources_D0/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D0/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management.

If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D0. The names
of the links are the same as the names of the directories they
point to.
14 changes: 14 additions & 0 deletions trunk/Documentation/ABI/testing/sysfs-devices-power_resources_D1
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
What: /sys/devices/.../power_resources_D1/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D1/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management and support ACPI
power state D1.

If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D1. The names
of the links are the same as the names of the directories they
point to.
14 changes: 14 additions & 0 deletions trunk/Documentation/ABI/testing/sysfs-devices-power_resources_D2
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
What: /sys/devices/.../power_resources_D2/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D2/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management and support ACPI
power state D2.

If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D2. The names
of the links are the same as the names of the directories they
point to.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
What: /sys/devices/.../power_resources_D3hot/
Date: January 2013
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Description:
The /sys/devices/.../power_resources_D3hot/ directory is only
present for device objects representing ACPI device nodes that
use ACPI power resources for power management and support ACPI
power state D3hot.

If present, it contains symbolic links to device directories
representing ACPI power resources that need to be turned on for
the given device node to be in ACPI power state D3hot. The
names of the links are the same as the names of the directories
they point to.
104 changes: 91 additions & 13 deletions trunk/drivers/acpi/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/sysfs.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include "sleep.h"
Expand Down Expand Up @@ -417,24 +418,101 @@ static void acpi_power_remove_dependent(struct acpi_power_resource *resource,
}
}

void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
static struct attribute *attrs[] = {
NULL,
};

static struct attribute_group attr_groups[] = {
[ACPI_STATE_D0] = {
.name = "power_resources_D0",
.attrs = attrs,
},
[ACPI_STATE_D1] = {
.name = "power_resources_D1",
.attrs = attrs,
},
[ACPI_STATE_D2] = {
.name = "power_resources_D2",
.attrs = attrs,
},
[ACPI_STATE_D3_HOT] = {
.name = "power_resources_D3hot",
.attrs = attrs,
},
};

static void acpi_power_hide_list(struct acpi_device *adev, int state)
{
struct acpi_device_power_state *ps = &adev->power.states[state];
struct acpi_power_resource_entry *entry;

if (list_empty(&ps->resources))
return;

list_for_each_entry_reverse(entry, &ps->resources, node) {
struct acpi_device *res_dev = &entry->resource->device;

sysfs_remove_link_from_group(&adev->dev.kobj,
attr_groups[state].name,
dev_name(&res_dev->dev));
}
sysfs_remove_group(&adev->dev.kobj, &attr_groups[state]);
}

static void acpi_power_expose_list(struct acpi_device *adev, int state)
{
if (adev->power.flags.power_resources) {
struct acpi_device_power_state *ps;
struct acpi_power_resource_entry *entry;

ps = &adev->power.states[ACPI_STATE_D0];
list_for_each_entry(entry, &ps->resources, node) {
struct acpi_power_resource *resource = entry->resource;

if (add)
acpi_power_add_dependent(resource, adev);
else
acpi_power_remove_dependent(resource, adev);
struct acpi_device_power_state *ps = &adev->power.states[state];
struct acpi_power_resource_entry *entry;
int ret;

if (list_empty(&ps->resources))
return;

ret = sysfs_create_group(&adev->dev.kobj, &attr_groups[state]);
if (ret)
return;

list_for_each_entry(entry, &ps->resources, node) {
struct acpi_device *res_dev = &entry->resource->device;

ret = sysfs_add_link_to_group(&adev->dev.kobj,
attr_groups[state].name,
&res_dev->dev.kobj,
dev_name(&res_dev->dev));
if (ret) {
acpi_power_hide_list(adev, state);
break;
}
}
}

void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
{
struct acpi_device_power_state *ps;
struct acpi_power_resource_entry *entry;
int state;

if (!adev->power.flags.power_resources)
return;

ps = &adev->power.states[ACPI_STATE_D0];
list_for_each_entry(entry, &ps->resources, node) {
struct acpi_power_resource *resource = entry->resource;

if (add)
acpi_power_add_dependent(resource, adev);
else
acpi_power_remove_dependent(resource, adev);
}

for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++) {
if (add)
acpi_power_expose_list(adev, state);
else
acpi_power_hide_list(adev, state);
}
}

int acpi_power_min_system_level(struct list_head *list)
{
struct acpi_power_resource_entry *entry;
Expand Down

0 comments on commit 6aa0ab6

Please sign in to comment.