summaryrefslogtreecommitdiff
path: root/drivers/acpi/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/power.c')
-rw-r--r--drivers/acpi/power.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 34f5ef11d427..f962047c6c85 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -459,57 +459,79 @@ static struct attribute_group attr_groups[] = {
},
};
-static void acpi_power_hide_list(struct acpi_device *adev, int state)
+static struct attribute_group wakeup_attr_group = {
+ .name = "power_resources_wakeup",
+ .attrs = attrs,
+};
+
+static void acpi_power_hide_list(struct acpi_device *adev,
+ struct list_head *resources,
+ struct attribute_group *attr_group)
{
- struct acpi_device_power_state *ps = &adev->power.states[state];
struct acpi_power_resource_entry *entry;
- if (list_empty(&ps->resources))
+ if (list_empty(resources))
return;
- list_for_each_entry_reverse(entry, &ps->resources, node) {
+ list_for_each_entry_reverse(entry, resources, node) {
struct acpi_device *res_dev = &entry->resource->device;
sysfs_remove_link_from_group(&adev->dev.kobj,
- attr_groups[state].name,
+ attr_group->name,
dev_name(&res_dev->dev));
}
- sysfs_remove_group(&adev->dev.kobj, &attr_groups[state]);
+ sysfs_remove_group(&adev->dev.kobj, attr_group);
}
-static void acpi_power_expose_list(struct acpi_device *adev, int state)
+static void acpi_power_expose_list(struct acpi_device *adev,
+ struct list_head *resources,
+ struct attribute_group *attr_group)
{
- struct acpi_device_power_state *ps = &adev->power.states[state];
struct acpi_power_resource_entry *entry;
int ret;
- if (list_empty(&ps->resources))
+ if (list_empty(resources))
return;
- ret = sysfs_create_group(&adev->dev.kobj, &attr_groups[state]);
+ ret = sysfs_create_group(&adev->dev.kobj, attr_group);
if (ret)
return;
- list_for_each_entry(entry, &ps->resources, node) {
+ list_for_each_entry(entry, resources, node) {
struct acpi_device *res_dev = &entry->resource->device;
ret = sysfs_add_link_to_group(&adev->dev.kobj,
- attr_groups[state].name,
+ attr_group->name,
&res_dev->dev.kobj,
dev_name(&res_dev->dev));
if (ret) {
- acpi_power_hide_list(adev, state);
+ acpi_power_hide_list(adev, resources, attr_group);
break;
}
}
}
+static void acpi_power_expose_hide(struct acpi_device *adev,
+ struct list_head *resources,
+ struct attribute_group *attr_group,
+ bool expose)
+{
+ if (expose)
+ acpi_power_expose_list(adev, resources, attr_group);
+ else
+ acpi_power_hide_list(adev, resources, attr_group);
+}
+
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->wakeup.flags.valid)
+ acpi_power_expose_hide(adev, &adev->wakeup.resources,
+ &wakeup_attr_group, add);
+
if (!adev->power.flags.power_resources)
return;
@@ -523,12 +545,10 @@ void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
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);
- }
+ for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++)
+ acpi_power_expose_hide(adev,
+ &adev->power.states[state].resources,
+ &attr_groups[state], add);
}
int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
@@ -824,7 +844,7 @@ static void acpi_release_power_resource(struct device *dev)
list_del(&resource->list_node);
mutex_unlock(&power_resource_list_lock);
- acpi_free_ids(device);
+ acpi_free_pnp_ids(&device->pnp);
kfree(resource);
}