diff options
Diffstat (limited to 'drivers/acpi/glue.c')
-rw-r--r-- | drivers/acpi/glue.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index e9e486f..35da181 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -95,31 +95,40 @@ static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) return ret; } -static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, - void *addr_p, void **ret_p) +/* Get device's handler per its address under its parent */ +struct acpi_find_child { + acpi_handle handle; + u64 address; +}; + +static acpi_status +do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) { - unsigned long long addr; acpi_status status; - - status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); - if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) { - *ret_p = handle; - return AE_CTRL_TERMINATE; + struct acpi_device_info *info; + struct acpi_find_child *find = context; + + status = acpi_get_object_info(handle, &info); + if (ACPI_SUCCESS(status)) { + if ((info->address == find->address) + && (info->valid & ACPI_VALID_ADR)) + find->handle = handle; + kfree(info); } return AE_OK; } acpi_handle acpi_get_child(acpi_handle parent, u64 address) { - void *ret = NULL; + struct acpi_find_child find = { NULL, address }; if (!parent) return NULL; - - acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL, - do_acpi_find_child, &address, &ret); - return (acpi_handle)ret; + acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, + 1, do_acpi_find_child, NULL, &find, NULL); + return find.handle; } + EXPORT_SYMBOL(acpi_get_child); static int acpi_bind_one(struct device *dev, acpi_handle handle) |