Loading drivers/acpi/glue.c +24 −11 Original line number Diff line number Diff line Loading @@ -79,6 +79,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) 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, void *not_used, void **ret_p) { Loading @@ -92,14 +95,17 @@ static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, 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; acpi_status status; status = acpi_bus_get_status_handle(handle, &sta); if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) return false; status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); if (status == AE_NOT_FOUND) sta_present = false; else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) return -ENODEV; if (is_bridge) { void *test = NULL; Loading @@ -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. */ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, 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 { u64 addr; bool is_bridge; acpi_handle ret; bool ret_checked; int ret_score; }; static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, Loading @@ -125,6 +132,7 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, struct find_child_context *context = data; unsigned long long addr; acpi_status status; int score; status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); if (ACPI_FAILURE(status) || addr != context->addr) Loading @@ -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 * just found. */ if (!context->ret_checked) { if (acpi_extra_checks_passed(context->ret, context->is_bridge)) if (!context->ret_score) { score = do_find_child_checks(context->ret, context->is_bridge); if (score == FIND_CHILD_MAX_SCORE) return AE_CTRL_TERMINATE; 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; return AE_CTRL_TERMINATE; } else if (score > context->ret_score) { context->ret = handle; context->ret_score = score; } return AE_OK; } Loading Loading
drivers/acpi/glue.c +24 −11 Original line number Diff line number Diff line Loading @@ -79,6 +79,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) 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, void *not_used, void **ret_p) { Loading @@ -92,14 +95,17 @@ static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, 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; acpi_status status; status = acpi_bus_get_status_handle(handle, &sta); if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) return false; status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); if (status == AE_NOT_FOUND) sta_present = false; else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) return -ENODEV; if (is_bridge) { void *test = NULL; Loading @@ -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. */ acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, 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 { u64 addr; bool is_bridge; acpi_handle ret; bool ret_checked; int ret_score; }; static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, Loading @@ -125,6 +132,7 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, struct find_child_context *context = data; unsigned long long addr; acpi_status status; int score; status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); if (ACPI_FAILURE(status) || addr != context->addr) Loading @@ -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 * just found. */ if (!context->ret_checked) { if (acpi_extra_checks_passed(context->ret, context->is_bridge)) if (!context->ret_score) { score = do_find_child_checks(context->ret, context->is_bridge); if (score == FIND_CHILD_MAX_SCORE) return AE_CTRL_TERMINATE; 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; return AE_CTRL_TERMINATE; } else if (score > context->ret_score) { context->ret = handle; context->ret_score = score; } return AE_OK; } Loading