ACPI: Add acpi_resource_consumer() to find device that claims a resource
Add acpi_resource_consumer(). This takes a struct resource and searches the ACPI namespace for a device whose current resource settings (_CRS) includes the resource. It returns the device if it exists, or NULL if no device uses the resource. If more than one device uses the resource (this may happen in the case of bridges), acpi_resource_consumer() returns the first one found by acpi_get_devices() in its modified depth-first walk of the namespace. Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
1001354ca3
commit
00710984ea
@ -664,3 +664,60 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,
|
|||||||
return (type & types) ? 0 : 1;
|
return (type & types) ? 0 : 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
|
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;
|
||||||
|
}
|
||||||
|
@ -419,6 +419,8 @@ static inline int acpi_dev_filter_resource_type_cb(struct acpi_resource *ares,
|
|||||||
return acpi_dev_filter_resource_type(ares, (unsigned long)arg);
|
return acpi_dev_filter_resource_type(ares, (unsigned long)arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct acpi_device *acpi_resource_consumer(struct resource *res);
|
||||||
|
|
||||||
int acpi_check_resource_conflict(const struct resource *res);
|
int acpi_check_resource_conflict(const struct resource *res);
|
||||||
|
|
||||||
int acpi_check_region(resource_size_t start, resource_size_t n,
|
int acpi_check_region(resource_size_t start, resource_size_t n,
|
||||||
@ -762,6 +764,11 @@ static inline int acpi_reconfig_notifier_unregister(struct notifier_block *nb)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct acpi_device *acpi_resource_consumer(struct resource *res)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !CONFIG_ACPI */
|
#endif /* !CONFIG_ACPI */
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
|
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
|
||||||
|
Loading…
Reference in New Issue
Block a user