diff options
Diffstat (limited to 'drivers/acpi/resource.c')
| -rw-r--r-- | drivers/acpi/resource.c | 57 | 
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 56241eb341f4..cb57962ef7c4 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -664,3 +664,60 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,  	return (type & types) ? 0 : 1;  }  EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type); + +static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res) +{ +	struct list_head resource_list; +	struct resource_entry *rentry; +	int ret, found = 0; + +	INIT_LIST_HEAD(&resource_list); +	ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); +	if (ret < 0) +		return 0; + +	list_for_each_entry(rentry, &resource_list, node) { +		if (resource_contains(rentry->res, res)) { +			found = 1; +			break; +		} + +	} + +	acpi_dev_free_resource_list(&resource_list); +	return found; +} + +static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth, +					 void *context, void **ret) +{ +	struct resource *res = context; +	struct acpi_device **consumer = (struct acpi_device **) ret; +	struct acpi_device *adev; + +	if (acpi_bus_get_device(handle, &adev)) +		return AE_OK; + +	if (acpi_dev_consumes_res(adev, res)) { +		*consumer = adev; +		return AE_CTRL_TERMINATE; +	} + +	return AE_OK; +} + +/** + * acpi_resource_consumer - Find the ACPI device that consumes @res. + * @res: Resource to search for. + * + * Search the current resource settings (_CRS) of every ACPI device node + * for @res.  If we find an ACPI device whose _CRS includes @res, return + * it.  Otherwise, return NULL. + */ +struct acpi_device *acpi_resource_consumer(struct resource *res) +{ +	struct acpi_device *consumer = NULL; + +	acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer); +	return consumer; +}  |