diff options
Diffstat (limited to 'drivers/acpi/power.c')
| -rw-r--r-- | drivers/acpi/power.c | 60 | 
1 files changed, 40 insertions, 20 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 34f5ef11d42..f962047c6c8 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);  }  |