From f2f51e7a13e2de5bedffbd693c43658d2d37854e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 30 Nov 2020 11:20:44 -0800 Subject: ACPICA: Remove extreaneous "the" in comments ACPICA commit f6eae3961bf39ad8beda70c001d1815780600e39 There are several ocurrances of "the the", remove the extraneous "the". Link: https://github.com/acpica/acpica/commit/f6eae396 Signed-off-by: Colin Ian King Signed-off-by: Bob Moore Signed-off-by: Erik Kaneda Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/accommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 89101e53324b..94e18bb76556 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -13,7 +13,7 @@ /* * Common set of includes for all ACPICA source files. * We put them here because we don't want to duplicate them - * in the the source code again and again. + * in the source code again and again. * * Note: The order of these include files is important. */ -- cgit v1.2.3 From 0306f035738fa6981e4e9eb68ab0316ceaa26c88 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 30 Nov 2020 11:20:45 -0800 Subject: ACPICA: Also handle "orphan" _REG methods for GPIO OpRegions ACPICA commit b9dc31e2fc67cf196fab5253a9a673bee68b2ef5 Before this commit acpi_ev_execute_reg_methods() had special handling to handle "orphan" (no matching op_region declared) _REG methods for EC nodes. On Intel Cherry Trail devices there are 2 possible ACPI op_regions for accessing GPIOs. The standard general_purpose_io op_region and the Cherry Trail specific user_defined 0x9X op_regions. Having 2 different types of op_regions leads to potential issues with checks for op_region availability, or in other words checks if _REG has been called for the op_region which the ACPI code wants to use. Except for the "orphan" EC handling, ACPICA core does not call _REG on an ACPI node which does not define an op_region matching the type being registered; and the reference design DSDT, from which most Cherry Trail DSDTs are derived, does not define general_purpose_io, nor user_defined(0x93) op_regions for the GPO2 (UID 3) device, because no pins were assigned ACPI controlled functions in the reference design. Together this leads to the perfect storm, at least on the Cherry Trail based Medion Akayo E1239T. This design does use a GPO2 pin from its ACPI code and has added the Cherry Trail specific user_defined(0x93) opregion to its GPO2 ACPI node to access this pin. But it uses a has _REG been called availability check for the standard general_purpose_io op_region. This clearly is a bug in the DSDT, but this does work under Windows. This issue leads to the intel_vbtn driver reporting the device always being in tablet-mode at boot, even if it is in laptop mode. Which in turn causes userspace to ignore touchpad events. So iow this issues causes the touchpad to not work at boot. This commit fixes this by extending the "orphan" _REG method handling to also apply to GPIO address-space handlers. Note it seems that Windows always calls "orphan" _REG methods so me may want to consider dropping the space-id check and always do "orphan" _REG method handling. Link: https://github.com/acpica/acpica/commit/b9dc31e2 Signed-off-by: Hans de Goede Signed-off-by: Erik Kaneda Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evregion.c | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 738d4b231f34..a8a4c8c9b9ef 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -21,7 +21,8 @@ extern u8 acpi_gbl_default_address_spaces[]; /* Local prototypes */ static void -acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node); +acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, + acpi_adr_space_type space_id); static acpi_status acpi_ev_reg_run(acpi_handle obj_handle, @@ -684,10 +685,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL, &info, NULL); - /* Special case for EC: handle "orphan" _REG methods with no region */ - - if (space_id == ACPI_ADR_SPACE_EC) { - acpi_ev_orphan_ec_reg_method(node); + /* + * Special case for EC and GPIO: handle "orphan" _REG methods with + * no region. + */ + if (space_id == ACPI_ADR_SPACE_EC || space_id == ACPI_ADR_SPACE_GPIO) { + acpi_ev_execute_orphan_reg_method(node, space_id); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, @@ -760,31 +763,28 @@ acpi_ev_reg_run(acpi_handle obj_handle, /******************************************************************************* * - * FUNCTION: acpi_ev_orphan_ec_reg_method + * FUNCTION: acpi_ev_execute_orphan_reg_method * - * PARAMETERS: ec_device_node - Namespace node for an EC device + * PARAMETERS: device_node - Namespace node for an ACPI device + * space_id - The address space ID * * RETURN: None * - * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC + * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI * device. This is a _REG method that has no corresponding region - * within the EC device scope. The orphan _REG method appears to - * have been enabled by the description of the ECDT in the ACPI - * specification: "The availability of the region space can be - * detected by providing a _REG method object underneath the - * Embedded Controller device." - * - * To quickly access the EC device, we use the ec_device_node used - * during EC handler installation. Otherwise, we would need to - * perform a time consuming namespace walk, executing _HID - * methods to find the EC device. + * within the device's scope. ACPI tables depending on these + * "orphan" _REG methods have been seen for both EC and GPIO + * Operation Regions. Presumably the Windows ACPI implementation + * always calls the _REG method independent of the presence of + * an actual Operation Region with the correct address space ID. * * MUTEX: Assumes the namespace is locked * ******************************************************************************/ static void -acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) +acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, + acpi_adr_space_type space_id) { acpi_handle reg_method; struct acpi_namespace_node *next_node; @@ -792,9 +792,9 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) struct acpi_object_list args; union acpi_object objects[2]; - ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); + ACPI_FUNCTION_TRACE(ev_execute_orphan_reg_method); - if (!ec_device_node) { + if (!device_node) { return_VOID; } @@ -804,7 +804,7 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) /* Get a handle to a _REG method immediately under the EC device */ - status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, ®_method); + status = acpi_get_handle(device_node, METHOD_NAME__REG, ®_method); if (ACPI_FAILURE(status)) { goto exit; /* There is no _REG method present */ } @@ -816,23 +816,23 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) * with other space IDs to be present; but the code below will then * execute the _REG method with the embedded_control space_ID argument. */ - next_node = acpi_ns_get_next_node(ec_device_node, NULL); + next_node = acpi_ns_get_next_node(device_node, NULL); while (next_node) { if ((next_node->type == ACPI_TYPE_REGION) && (next_node->object) && - (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { + (next_node->object->region.space_id == space_id)) { goto exit; /* Do not execute the _REG */ } - next_node = acpi_ns_get_next_node(ec_device_node, next_node); + next_node = acpi_ns_get_next_node(device_node, next_node); } - /* Evaluate the _REG(embedded_control,Connect) method */ + /* Evaluate the _REG(space_id,Connect) method */ args.count = 2; args.pointer = objects; objects[0].type = ACPI_TYPE_INTEGER; - objects[0].integer.value = ACPI_ADR_SPACE_EC; + objects[0].integer.value = space_id; objects[1].type = ACPI_TYPE_INTEGER; objects[1].integer.value = ACPI_REG_CONNECT; -- cgit v1.2.3 From 0766efdf9a9d24eaefe260c787f49af225018b16 Mon Sep 17 00:00:00 2001 From: Erik Kaneda Date: Mon, 30 Nov 2020 11:20:46 -0800 Subject: ACPICA: Add function trace macros to improve debugging ACPICA commit 87b8dba05b4cf8c111948327023c710e2b6b5a05 The namespace repair mechanism does not have function tracing macros. Add several trace macros to improve debuggability. Link: https://github.com/acpica/acpica/commit/87b8dba0 Signed-off-by: Erik Kaneda Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nspredef.c | 10 ++++++---- drivers/acpi/acpica/nsprepkg.c | 38 ++++++++++++++++++++------------------ drivers/acpi/acpica/nsrepair2.c | 24 ++++++++++++++---------- 3 files changed, 40 insertions(+), 32 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 0cea9c363ace..167a1c2495ab 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -71,11 +71,13 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, acpi_status status; const union acpi_predefined_info *predefined; + ACPI_FUNCTION_TRACE(ns_check_return_value); + /* If not a predefined name, we cannot validate the return object */ predefined = info->predefined; if (!predefined) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -83,7 +85,7 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, * validate the return object */ if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -102,7 +104,7 @@ acpi_ns_check_return_value(struct acpi_namespace_node *node, if (acpi_gbl_disable_auto_repair || (!predefined->info.expected_btypes) || (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* @@ -163,7 +165,7 @@ exit: node->flags |= ANOBJ_EVALUATED; } - return (status); + return_ACPI_STATUS(status); } /******************************************************************************* diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index 237b3ddeb075..1875b1cba202 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c @@ -59,7 +59,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, u32 count; u32 i; - ACPI_FUNCTION_NAME(ns_check_package); + ACPI_FUNCTION_TRACE(ns_check_package); /* The package info for this name is in the next table entry */ @@ -88,14 +88,14 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, */ if (!count) { if (package->ret_info.type == ACPI_PTYPE1_VAR) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, "Return Package has no elements (empty)")); - return (AE_AML_OPERAND_VALUE); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } /* @@ -152,7 +152,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, package->ret_info. object_type1, i); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } elements++; @@ -186,7 +186,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, object_type[i], i); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } } else { /* These are the optional package elements */ @@ -198,7 +198,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, tail_object_type, i); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } } @@ -214,7 +214,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, acpi_ns_check_object_type(info, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } elements++; @@ -234,7 +234,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, acpi_ns_check_object_type(info, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } /* @@ -279,7 +279,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, acpi_ns_wrap_with_package(info, return_object, return_object_ptr); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } /* Update locals to point to the new package (of 1 element) */ @@ -316,7 +316,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, package->ret_info. object_type1, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } /* Validate length of the UUID buffer */ @@ -326,14 +326,14 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, info->full_pathname, info->node_flags, "Invalid length for UUID Buffer")); - return (AE_AML_OPERAND_VALUE); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } status = acpi_ns_check_object_type(info, elements + 1, package->ret_info. object_type2, 0); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } elements += 2; @@ -350,10 +350,10 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, "Invalid internal return type in table entry: %X", package->ret_info.type)); - return (AE_AML_INTERNAL); + return_ACPI_STATUS(AE_AML_INTERNAL); } - return (status); + return_ACPI_STATUS(status); package_too_small: @@ -363,7 +363,7 @@ package_too_small: "Return Package is too small - found %u elements, expected %u", count, expected_count)); - return (AE_AML_OPERAND_VALUE); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } /******************************************************************************* @@ -708,6 +708,8 @@ acpi_ns_check_package_elements(struct acpi_evaluate_info *info, acpi_status status; u32 i; + ACPI_FUNCTION_TRACE(ns_check_package_elements); + /* * Up to two groups of package elements are supported by the data * structure. All elements in each group must be of the same type. @@ -717,7 +719,7 @@ acpi_ns_check_package_elements(struct acpi_evaluate_info *info, status = acpi_ns_check_object_type(info, this_element, type1, i + start_index); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } this_element++; @@ -728,11 +730,11 @@ acpi_ns_check_package_elements(struct acpi_evaluate_info *info, type2, (i + count1 + start_index)); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } this_element++; } - return (AE_OK); + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 125143c41bb8..24c197d91f29 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -155,15 +155,17 @@ acpi_ns_complex_repairs(struct acpi_evaluate_info *info, const struct acpi_repair_info *predefined; acpi_status status; + ACPI_FUNCTION_TRACE(ns_complex_repairs); + /* Check if this name is in the list of repairable names */ predefined = acpi_ns_match_complex_repair(node); if (!predefined) { - return (validate_status); + return_ACPI_STATUS(validate_status); } status = predefined->repair_function(info, return_object_ptr); - return (status); + return_ACPI_STATUS(status); } /****************************************************************************** @@ -344,17 +346,19 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, u16 original_ref_count; u32 i; + ACPI_FUNCTION_TRACE(ns_repair_CID); + /* Check for _CID as a simple string */ if (return_object->common.type == ACPI_TYPE_STRING) { status = acpi_ns_repair_HID(info, return_object_ptr); - return (status); + return_ACPI_STATUS(status); } /* Exit if not a Package */ if (return_object->common.type != ACPI_TYPE_PACKAGE) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* Examine each element of the _CID package */ @@ -366,7 +370,7 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, status = acpi_ns_repair_HID(info, element_ptr); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } if (original_element != *element_ptr) { @@ -380,7 +384,7 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, element_ptr++; } - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /****************************************************************************** @@ -500,7 +504,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, /* We only care about string _HID objects (not integers) */ if (return_object->common.type != ACPI_TYPE_STRING) { - return (AE_OK); + return_ACPI_STATUS(AE_OK); } if (return_object->string.length == 0) { @@ -511,14 +515,14 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, /* Return AE_OK anyway, let driver handle it */ info->return_flags |= ACPI_OBJECT_REPAIRED; - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /* It is simplest to always create a new string object */ new_string = acpi_ut_create_string_object(return_object->string.length); if (!new_string) { - return (AE_NO_MEMORY); + return_ACPI_STATUS(AE_NO_MEMORY); } /* @@ -551,7 +555,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, acpi_ut_remove_reference(return_object); *return_object_ptr = new_string; - return (AE_OK); + return_ACPI_STATUS(AE_OK); } /****************************************************************************** -- cgit v1.2.3 From 32cf1a12cad43358e47dac8014379c2f33dfbed4 Mon Sep 17 00:00:00 2001 From: Erik Kaneda Date: Mon, 30 Nov 2020 11:20:47 -0800 Subject: ACPICA: Interpreter: fix memory leak by using existing buffer ACPICA commit 52d1da5dcbd79a722b70f02a1a83f04088f51ff6 There was a memory leak that ocurred when a _CID object is defined as a package containing string objects. When _CID is checked for any possible repairs, it calls a helper function to repair _HID (because _CID basically contains multiple _HID entries). The _HID repair function assumes that string objects are standalone objects that are not contained inside of any packages. The _HID repair function replaces the string object with a brand new object and attempts to delete the old object by decrementing the reference count of the old object. Strings inside of packages have a reference count of 2 so the _HID repair function leaves this object in a dangling state and causes a memory leak. Instead of allocating a brand new object and removing the old object, use the existing object when repairing the _HID object. Link: https://github.com/acpica/acpica/commit/52d1da5d Signed-off-by: Erik Kaneda Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsrepair2.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 24c197d91f29..d2c8d8279e7a 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -495,9 +495,8 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, union acpi_operand_object **return_object_ptr) { union acpi_operand_object *return_object = *return_object_ptr; - union acpi_operand_object *new_string; - char *source; char *dest; + char *source; ACPI_FUNCTION_NAME(ns_repair_HID); @@ -518,13 +517,6 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, return_ACPI_STATUS(AE_OK); } - /* It is simplest to always create a new string object */ - - new_string = acpi_ut_create_string_object(return_object->string.length); - if (!new_string) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - /* * Remove a leading asterisk if present. For some unknown reason, there * are many machines in the field that contains IDs like this. @@ -534,7 +526,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, source = return_object->string.pointer; if (*source == '*') { source++; - new_string->string.length--; + return_object->string.length--; ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, "%s: Removed invalid leading asterisk\n", @@ -549,12 +541,11 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, * "NNNN####" where N is an uppercase letter or decimal digit, and * # is a hex digit. */ - for (dest = new_string->string.pointer; *source; dest++, source++) { + for (dest = return_object->string.pointer; *source; dest++, source++) { *dest = (char)toupper((int)*source); } + return_object->string.pointer[return_object->string.length] = 0; - acpi_ut_remove_reference(return_object); - *return_object_ptr = new_string; return_ACPI_STATUS(AE_OK); } -- cgit v1.2.3 From 637b9f1a1194cc671bac0039824cc472a2960b2f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 21 Nov 2020 21:30:34 +0100 Subject: ACPI: scan: Add acpi_info_matches_hids() helper acpi_device_dep_initialize() disergards _DEP "suppliers" with a _HID of "INT3396" and checks this using an acpi_device_info struct. Because in general there are other device IDs that need to be treated in the same way, add acpi_info_matches_hids() which checks a list of _HIDs for this purpose and switch acpi_device_dep_initialize() over to using it. Signed-off-by: Hans de Goede [ rjw: Changelog rewrite ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index bc6a79e33220..e949265d5667 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -719,6 +719,28 @@ int acpi_device_add(struct acpi_device *device, /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ +static bool acpi_info_matches_hids(struct acpi_device_info *info, + const char * const hids[]) +{ + int i; + + if (!(info->valid & ACPI_VALID_HID)) + return false; + + for (i = 0; hids[i]; i++) { + if (!strcmp(info->hardware_id.string, hids[i])) + return true; + } + + return false; +} + +/* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */ +static const char * const acpi_ignore_dep_hids[] = { + "INT3396", /* Windows System Power Management Controller */ + NULL +}; + static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) { struct acpi_device *device = NULL; @@ -1833,13 +1855,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) continue; } - /* - * Skip the dependency of Windows System Power - * Management Controller - */ - skip = info->valid & ACPI_VALID_HID && - !strcmp(info->hardware_id.string, "INT3396"); - + skip = acpi_info_matches_hids(info, acpi_ignore_dep_hids); kfree(info); if (skip) -- cgit v1.2.3 From 6091b2631032adafa1c8c0bd181aa5d153185c6f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 21 Nov 2020 21:30:35 +0100 Subject: ACPI: scan: Call acpi_get_object_info() from acpi_add_single_object() Call acpi_get_object_info() from acpi_add_single_object() instead of calling it from acpi_set_pnp_ids() and pass the result down to the latter so as to allow acpi_add_single_object() to use that data for other purposes. Signed-off-by: Hans de Goede [ rjw: Changelog rewrite ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/internal.h | 3 ++- drivers/acpi/power.c | 2 +- drivers/acpi/scan.c | 22 ++++++++++++---------- 3 files changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 43411a7457cd..68f79e3fdb98 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -105,7 +105,8 @@ struct acpi_device_bus_id { int acpi_device_add(struct acpi_device *device, void (*release)(struct device *)); void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, - int type, unsigned long long sta); + int type, unsigned long long sta, + struct acpi_device_info *info); int acpi_device_setup_files(struct acpi_device *dev); void acpi_device_remove_files(struct acpi_device *dev); void acpi_device_add_finalize(struct acpi_device *device); diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 837b875d075e..228b0af3fcc6 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -939,7 +939,7 @@ int acpi_add_power_resource(acpi_handle handle) device = &resource->device; acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER, - ACPI_STA_DEFAULT); + ACPI_STA_DEFAULT, NULL); mutex_init(&resource->resource_lock); INIT_LIST_HEAD(&resource->list_node); INIT_LIST_HEAD(&resource->dependents); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e949265d5667..25a46ae24229 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1258,10 +1258,8 @@ static bool acpi_object_is_system_bus(acpi_handle handle) } static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, - int device_type) + int device_type, struct acpi_device_info *info) { - acpi_status status; - struct acpi_device_info *info; struct acpi_pnp_device_id_list *cid_list; int i; @@ -1272,8 +1270,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, break; } - status = acpi_get_object_info(handle, &info); - if (ACPI_FAILURE(status)) { + if (!info) { pr_err(PREFIX "%s: Error reading device info\n", __func__); return; @@ -1298,8 +1295,6 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, if (info->valid & ACPI_VALID_CLS) acpi_add_id(pnp, info->class_code.string); - kfree(info); - /* * Some devices don't reliably have _HIDs & _CIDs, so add * synthetic HIDs to make sure drivers can find them. @@ -1605,7 +1600,8 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) } void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, - int type, unsigned long long sta) + int type, unsigned long long sta, + struct acpi_device_info *info) { INIT_LIST_HEAD(&device->pnp.ids); device->device_type = type; @@ -1614,7 +1610,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, device->fwnode.ops = &acpi_device_fwnode_ops; acpi_set_device_status(device, sta); acpi_device_get_busid(device); - acpi_set_pnp_ids(handle, &device->pnp, type); + acpi_set_pnp_ids(handle, &device->pnp, type, info); acpi_init_properties(device); acpi_bus_get_flags(device); device->flags.match_driver = false; @@ -1642,14 +1638,20 @@ static int acpi_add_single_object(struct acpi_device **child, int result; struct acpi_device *device; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_device_info *info = NULL; + + if (handle != ACPI_ROOT_OBJECT && type == ACPI_BUS_TYPE_DEVICE) + acpi_get_object_info(handle, &info); device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); if (!device) { printk(KERN_ERR PREFIX "Memory allocation error\n"); + kfree(info); return -ENOMEM; } - acpi_init_device_object(device, handle, type, sta); + acpi_init_device_object(device, handle, type, sta, info); + kfree(info); /* * For ACPI_BUS_TYPE_DEVICE getting the status is delayed till here so * that we can call acpi_bus_get_status() and use its quirk handling. -- cgit v1.2.3 From 2ef33ee7f4f68d77b852bb2c946fc2f8f136a3c1 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Sat, 5 Dec 2020 16:29:41 +0100 Subject: ACPI: scan: Add PNP0D80 to the _DEP exceptions list The PNP0D80 ("Windows-compatible System Power Management Controller") device ID is used for identifying the special device object providing the LPI (Low-power S0 Idle) _DSM interface [1]. That device object does not supply any operation regions, but it appears in _DEP lists for other devices in the ACPI tables on some systems to enforce specific enumeration ordering that does not matter for Linux. For this reason, _DEP list entries pointing to the device object whose _CID returns PNP0D80 need not be taken into account as real operation region dependencies, so add that device ID to the list of device IDs for which the matching _DEP list entries should be ignored. Accordingly, update the function used for matching device IDs in that list to allow it to check _CID as well as _HID and rename it to acpi_info_matches_ids(). Link: https://www.uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf # [1] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 25a46ae24229..b44b2d6b6b22 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -719,25 +719,40 @@ int acpi_device_add(struct acpi_device *device, /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ -static bool acpi_info_matches_hids(struct acpi_device_info *info, - const char * const hids[]) +static bool acpi_info_matches_ids(struct acpi_device_info *info, + const char * const ids[]) { + struct acpi_pnp_device_id_list *cid_list = NULL; int i; if (!(info->valid & ACPI_VALID_HID)) return false; - for (i = 0; hids[i]; i++) { - if (!strcmp(info->hardware_id.string, hids[i])) + if (info->valid & ACPI_VALID_CID) + cid_list = &info->compatible_id_list; + + for (i = 0; ids[i]; i++) { + int j; + + if (!strcmp(info->hardware_id.string, ids[i])) return true; + + if (!cid_list) + continue; + + for (j = 0; j < cid_list->count; j++) { + if (!strcmp(cid_list->ids[j].string, ids[i])) + return true; + } } return false; } /* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */ -static const char * const acpi_ignore_dep_hids[] = { +static const char * const acpi_ignore_dep_ids[] = { "INT3396", /* Windows System Power Management Controller */ + "PNP0D80", /* Windows-compatible System Power Management Controller */ NULL }; @@ -1857,7 +1872,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) continue; } - skip = acpi_info_matches_hids(info, acpi_ignore_dep_hids); + skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids); kfree(info); if (skip) -- cgit v1.2.3 From b36b1e9db41fcff860624ece91c71b62f2ad6754 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Mon, 7 Dec 2020 17:55:11 +0100 Subject: ACPI: scan: Drop INT3396 from acpi_ignore_dep_ids[] According to Hans, all device objects where the _HID returns "INT3396" also have a _CID returning "PNP0D80", so the former need not be present in acpi_ignore_dep_ids[] any more. Link: https://lore.kernel.org/linux-acpi/52a2b98c-6bf3-760b-eca9-93cf05fb4877@redhat.com/ Suggested-by: Hans de Goede Signed-off-by: Rafael J. Wysocki Acked-by: Hans de Goede --- drivers/acpi/scan.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b44b2d6b6b22..560385e35d3d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -751,7 +751,6 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info, /* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */ static const char * const acpi_ignore_dep_ids[] = { - "INT3396", /* Windows System Power Management Controller */ "PNP0D80", /* Windows-compatible System Power Management Controller */ NULL }; -- cgit v1.2.3 From 91438aebcd56ed3cfa480e4546c7b06e9db3c73c Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Mon, 7 Dec 2020 18:46:06 +0100 Subject: ACPI: scan: Fix up _DEP-related terminology with supplier/consumer The ACPI namespace scanning code uses the terms master/slave when populating the list of _DEP dependencies, but that use has no external exposures and is not mandated by nor associated with any external specifications. Change the language used through-out to supplier/consumer. No functional impact. Signed-off-by: Rafael J. Wysocki Reviewed-by: Hans de Goede --- drivers/acpi/scan.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 560385e35d3d..37317e0ed65d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -51,8 +51,8 @@ static u64 spcr_uart_addr; struct acpi_dep_data { struct list_head node; - acpi_handle master; - acpi_handle slave; + acpi_handle supplier; + acpi_handle consumer; }; void acpi_scan_lock_acquire(void) @@ -1881,8 +1881,8 @@ static void acpi_device_dep_initialize(struct acpi_device *adev) if (!dep) return; - dep->master = dep_devices.handles[i]; - dep->slave = adev->handle; + dep->supplier = dep_devices.handles[i]; + dep->consumer = adev->handle; adev->dep_unmet++; mutex_lock(&acpi_dep_list_lock); @@ -2058,8 +2058,8 @@ void acpi_walk_dep_device_list(acpi_handle handle) mutex_lock(&acpi_dep_list_lock); list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) { - if (dep->master == handle) { - acpi_bus_get_device(dep->slave, &adev); + if (dep->supplier == handle) { + acpi_bus_get_device(dep->consumer, &adev); if (!adev) continue; -- cgit v1.2.3