|
@@ -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)
|