Commit 0a733e6e authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'acpi-bind'

* acpi-bind:
  ACPI / bind: Prefer device objects with _STA to those without it
parents 1a7b0ecb 11b88ee2
...@@ -79,6 +79,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) ...@@ -79,6 +79,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
return ret; return ret;
} }
#define FIND_CHILD_MIN_SCORE 1
#define FIND_CHILD_MAX_SCORE 2
static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
void *not_used, void **ret_p) void *not_used, void **ret_p)
{ {
...@@ -92,14 +95,17 @@ static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, ...@@ -92,14 +95,17 @@ static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
return AE_OK; return AE_OK;
} }
static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge) static int do_find_child_checks(acpi_handle handle, bool is_bridge)
{ {
bool sta_present = true;
unsigned long long sta; unsigned long long sta;
acpi_status status; acpi_status status;
status = acpi_bus_get_status_handle(handle, &sta); status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) if (status == AE_NOT_FOUND)
return false; sta_present = false;
else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
return -ENODEV;
if (is_bridge) { if (is_bridge) {
void *test = NULL; void *test = NULL;
...@@ -107,16 +113,17 @@ static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge) ...@@ -107,16 +113,17 @@ static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge)
/* Check if this object has at least one child device. */ /* Check if this object has at least one child device. */
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
acpi_dev_present, NULL, NULL, &test); acpi_dev_present, NULL, NULL, &test);
return !!test; if (!test)
return -ENODEV;
} }
return true; return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
} }
struct find_child_context { struct find_child_context {
u64 addr; u64 addr;
bool is_bridge; bool is_bridge;
acpi_handle ret; acpi_handle ret;
bool ret_checked; int ret_score;
}; };
static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
...@@ -125,6 +132,7 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, ...@@ -125,6 +132,7 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
struct find_child_context *context = data; struct find_child_context *context = data;
unsigned long long addr; unsigned long long addr;
acpi_status status; acpi_status status;
int score;
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
if (ACPI_FAILURE(status) || addr != context->addr) if (ACPI_FAILURE(status) || addr != context->addr)
...@@ -144,15 +152,20 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, ...@@ -144,15 +152,20 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
* its handle if so. Second, check the same for the object that we've * its handle if so. Second, check the same for the object that we've
* just found. * just found.
*/ */
if (!context->ret_checked) { if (!context->ret_score) {
if (acpi_extra_checks_passed(context->ret, context->is_bridge)) score = do_find_child_checks(context->ret, context->is_bridge);
if (score == FIND_CHILD_MAX_SCORE)
return AE_CTRL_TERMINATE; return AE_CTRL_TERMINATE;
else else
context->ret_checked = true; context->ret_score = score;
} }
if (acpi_extra_checks_passed(handle, context->is_bridge)) { score = do_find_child_checks(handle, context->is_bridge);
if (score == FIND_CHILD_MAX_SCORE) {
context->ret = handle; context->ret = handle;
return AE_CTRL_TERMINATE; return AE_CTRL_TERMINATE;
} else if (score > context->ret_score) {
context->ret = handle;
context->ret_score = score;
} }
return AE_OK; return AE_OK;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment