]> Pileus Git - ~andy/linux/blobdiff - drivers/acpi/power.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux...
[~andy/linux] / drivers / acpi / power.c
index 34f5ef11d427bd8f9acb4690b6c64b41d9c331b0..f962047c6c85591762893ada0a73549913b03d85 100644 (file)
@@ -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);
 }