summaryrefslogtreecommitdiff
path: root/drivers/acpi/glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/glue.c')
-rw-r--r--drivers/acpi/glue.c35
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)