diff options
author | Linus Torvalds | 2020-12-15 16:39:06 -0800 |
---|---|---|
committer | Linus Torvalds | 2020-12-15 16:39:06 -0800 |
commit | aab7ce2b099bd9df82573cd3170acf6518fdebeb (patch) | |
tree | 88caa27e82f334f1f949dacc874e7af1b276af7e /drivers/acpi | |
parent | b4ec805464a4a0299216a003278351d0b4806450 (diff) | |
parent | 38a0925c5fc89689433f2a2ad415982397cf626e (diff) |
Merge tag 'acpi-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki:
"These update the ACPICA code in the kernel to upstream revision
20201113, fix and clean up some resources manipulation code, extend
the enumeration and gpio-line-names property documentation, clean up
the handling of _DEP during device enumeration, add a new backlight
DMI quirk, clean up transaction handling in the EC driver and make
some assorted janitorial changes.
Specifics:
- Update ACPICA code in the kernel to upstream revision 20201113 with
changes as follows:
* Add 5 new UUIDs to the known UUID table (Bob Moore)
* Remove extreaneous "the" in comments (Colin Ian King)
* Add function trace macros to improve debugging (Erik Kaneda)
* Fix interpreter memory leak (Erik Kaneda)
* Handle "orphan" _REG for GPIO OpRegions (Hans de Goede)
- Introduce resource_union() and resource_intersection() helpers and
clean up some resource-manipulation code with the help of them
(Andy Shevchenko)
- Revert problematic commit related to the handling of resources in
the ACPI core (Daniel Scally)
- Extend the ACPI device enumeration documentation and the
gpio-line-names _DSD property documentation, clean up the latter
(Flavio Suligoi)
- Clean up _DEP handling during device enumeration, modify the list
of _DEP exceptions and the handling of it and fix up terminology
related to _DEP (Hans de Goede, Rafael Wysocki)
- Eliminate in_interrupt() usage from the ACPI EC driver (Sebastian
Andrzej Siewior)
- Clean up the advance_transaction() routine and related code in the
ACPI EC driver (Rafael Wysocki)
- Add new backlight quirk for GIGABYTE GB-BXBT-2807 (Jasper St
Pierre)
- Make assorted janitorial changes in several ACPI-related pieces of
code (Hanjun Guo, Jason Yan, Punit Agrawal)"
* tag 'acpi-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (40 commits)
ACPI: scan: Fix up _DEP-related terminology with supplier/consumer
ACPI: scan: Drop INT3396 from acpi_ignore_dep_ids[]
ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807
Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources walks"
ACPI: scan: Add PNP0D80 to the _DEP exceptions list
ACPI: scan: Call acpi_get_object_info() from acpi_add_single_object()
ACPI: scan: Add acpi_info_matches_hids() helper
ACPICA: Update version to 20201113
ACPICA: Interpreter: fix memory leak by using existing buffer
ACPICA: Add function trace macros to improve debugging
ACPICA: Also handle "orphan" _REG methods for GPIO OpRegions
ACPICA: Remove extreaneous "the" in comments
ACPICA: Add 5 new UUIDs to the known UUID table
resource: provide meaningful MODULE_LICENSE() in test suite
ASoC: Intel: catpt: Replace open coded variant of resource_intersection()
ACPI: processor: Drop duplicate setting of shared_cpu_map
ACPI: EC: Clean up status flags checks in advance_transaction()
ACPI: EC: Untangle error handling in advance_transaction()
ACPI: EC: Simplify error handling in advance_transaction()
ACPI: EC: Rename acpi_ec_is_gpe_raised()
...
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpi_dbg.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpi_watchdog.c | 6 | ||||
-rw-r--r-- | drivers/acpi/acpica/accommon.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/evregion.c | 54 | ||||
-rw-r--r-- | drivers/acpi/acpica/nspredef.c | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsprepkg.c | 38 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsrepair2.c | 39 | ||||
-rw-r--r-- | drivers/acpi/apei/apei-base.c | 2 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 117 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 3 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 4 | ||||
-rw-r--r-- | drivers/acpi/power.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 1 | ||||
-rw-r--r-- | drivers/acpi/processor_perflib.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_thermal.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_throttling.c | 1 | ||||
-rw-r--r-- | drivers/acpi/resource.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sbs.c | 24 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 78 | ||||
-rw-r--r-- | drivers/acpi/tiny-power-button.c | 4 | ||||
-rw-r--r-- | drivers/acpi/video_detect.c | 7 |
21 files changed, 194 insertions, 211 deletions
diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c index fb7290338593..d50261d05f3a 100644 --- a/drivers/acpi/acpi_dbg.c +++ b/drivers/acpi/acpi_dbg.c @@ -117,13 +117,6 @@ static inline bool __acpi_aml_busy(void) return false; } -static inline bool __acpi_aml_opened(void) -{ - if (acpi_aml_io.flags & ACPI_AML_OPEN) - return true; - return false; -} - static inline bool __acpi_aml_used(void) { return acpi_aml_io.usages ? true : false; diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 5c1e9ea43123..ca28183f4d13 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -151,11 +151,7 @@ void __init acpi_watchdog_init(void) found = false; resource_list_for_each_entry(rentry, &resource_list) { if (rentry->res->flags == res.flags && - resource_overlaps(rentry->res, &res)) { - if (res.start < rentry->res->start) - rentry->res->start = res.start; - if (res.end > rentry->res->end) - rentry->res->end = res.end; + resource_union(rentry->res, &res, rentry->res)) { found = true; break; } 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. */ 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; 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..d2c8d8279e7a 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); } /****************************************************************************** @@ -491,16 +495,15 @@ 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); /* 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 +514,7 @@ 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); - } - - /* 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_OK); } /* @@ -530,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", @@ -545,13 +541,12 @@ 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 (AE_OK); + return_ACPI_STATUS(AE_OK); } /****************************************************************************** diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 3294cc8dc073..c7fdb12c3310 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -287,7 +287,7 @@ struct apei_res { }; /* Collect all resources requested, to avoid conflict */ -struct apei_resources apei_resources_all = { +static struct apei_resources apei_resources_all = { .iomem = LIST_HEAD_INIT(apei_resources_all.iomem), .ioport = LIST_HEAD_INIT(apei_resources_all.ioport), }; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e0cb1bcfffb2..13565629ce0a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -169,7 +169,7 @@ struct acpi_ec_query { }; static int acpi_ec_query(struct acpi_ec *ec, u8 *data); -static void advance_transaction(struct acpi_ec *ec); +static void advance_transaction(struct acpi_ec *ec, bool interrupt); static void acpi_ec_event_handler(struct work_struct *work); static void acpi_ec_event_processor(struct work_struct *work); @@ -335,12 +335,12 @@ static const char *acpi_ec_cmd_string(u8 cmd) * GPE Registers * -------------------------------------------------------------------------- */ -static inline bool acpi_ec_is_gpe_raised(struct acpi_ec *ec) +static inline bool acpi_ec_gpe_status_set(struct acpi_ec *ec) { acpi_event_status gpe_status = 0; (void)acpi_get_gpe_status(NULL, ec->gpe, &gpe_status); - return (gpe_status & ACPI_EVENT_FLAG_STATUS_SET) ? true : false; + return !!(gpe_status & ACPI_EVENT_FLAG_STATUS_SET); } static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) @@ -351,14 +351,14 @@ static inline void acpi_ec_enable_gpe(struct acpi_ec *ec, bool open) BUG_ON(ec->reference_count < 1); acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); } - if (acpi_ec_is_gpe_raised(ec)) { + if (acpi_ec_gpe_status_set(ec)) { /* * On some platforms, EN=1 writes cannot trigger GPE. So * software need to manually trigger a pseudo GPE event on * EN=1 writes. */ ec_dbg_raw("Polling quirk"); - advance_transaction(ec); + advance_transaction(ec, false); } } @@ -372,23 +372,6 @@ static inline void acpi_ec_disable_gpe(struct acpi_ec *ec, bool close) } } -static inline void acpi_ec_clear_gpe(struct acpi_ec *ec) -{ - /* - * GPE STS is a W1C register, which means: - * 1. Software can clear it without worrying about clearing other - * GPEs' STS bits when the hardware sets them in parallel. - * 2. As long as software can ensure only clearing it when it is - * set, hardware won't set it in parallel. - * So software can clear GPE in any contexts. - * Warning: do not move the check into advance_transaction() as the - * EC commands will be sent without GPE raised. - */ - if (!acpi_ec_is_gpe_raised(ec)) - return; - acpi_clear_gpe(NULL, ec->gpe); -} - /* -------------------------------------------------------------------------- * Transaction Management * -------------------------------------------------------------------------- */ @@ -488,7 +471,7 @@ static inline void __acpi_ec_enable_event(struct acpi_ec *ec) * Unconditionally invoke this once after enabling the event * handling mechanism to detect the pending events. */ - advance_transaction(ec); + advance_transaction(ec, false); } static inline void __acpi_ec_disable_event(struct acpi_ec *ec) @@ -632,24 +615,41 @@ static inline void ec_transaction_transition(struct acpi_ec *ec, unsigned long f } } -static void advance_transaction(struct acpi_ec *ec) +static void acpi_ec_spurious_interrupt(struct acpi_ec *ec, struct transaction *t) { - struct transaction *t; - u8 status; + if (t->irq_count < ec_storm_threshold) + ++t->irq_count; + + /* Trigger if the threshold is 0 too. */ + if (t->irq_count == ec_storm_threshold) + acpi_ec_mask_events(ec); +} + +static void advance_transaction(struct acpi_ec *ec, bool interrupt) +{ + struct transaction *t = ec->curr; bool wakeup = false; + u8 status; + + ec_dbg_stm("%s (%d)", interrupt ? "IRQ" : "TASK", smp_processor_id()); - ec_dbg_stm("%s (%d)", in_interrupt() ? "IRQ" : "TASK", - smp_processor_id()); /* - * By always clearing STS before handling all indications, we can - * ensure a hardware STS 0->1 change after this clearing can always - * trigger a GPE interrupt. + * Clear GPE_STS upfront to allow subsequent hardware GPE_STS 0->1 + * changes to always trigger a GPE interrupt. + * + * GPE STS is a W1C register, which means: + * + * 1. Software can clear it without worrying about clearing the other + * GPEs' STS bits when the hardware sets them in parallel. + * + * 2. As long as software can ensure only clearing it when it is set, + * hardware won't set it in parallel. */ - if (ec->gpe >= 0) - acpi_ec_clear_gpe(ec); + if (ec->gpe >= 0 && acpi_ec_gpe_status_set(ec)) + acpi_clear_gpe(NULL, ec->gpe); status = acpi_ec_read_status(ec); - t = ec->curr; + /* * Another IRQ or a guarded polling mode advancement is detected, * the next QR_EC submission is then allowed. @@ -661,56 +661,43 @@ static void advance_transaction(struct acpi_ec *ec) clear_bit(EC_FLAGS_QUERY_GUARDING, &ec->flags); acpi_ec_complete_query(ec); } + if (!t) + goto out; } - if (!t) - goto err; + if (t->flags & ACPI_EC_COMMAND_POLL) { if (t->wlen > t->wi) { - if ((status & ACPI_EC_FLAG_IBF) == 0) + if (!(status & ACPI_EC_FLAG_IBF)) acpi_ec_write_data(ec, t->wdata[t->wi++]); - else - goto err; + else if (interrupt && !(status & ACPI_EC_FLAG_SCI)) + acpi_ec_spurious_interrupt(ec, t); } else if (t->rlen > t->ri) { - if ((status & ACPI_EC_FLAG_OBF) == 1) { + if (status & ACPI_EC_FLAG_OBF) { t->rdata[t->ri++] = acpi_ec_read_data(ec); if (t->rlen == t->ri) { ec_transaction_transition(ec, ACPI_EC_COMMAND_COMPLETE); + wakeup = true; if (t->command == ACPI_EC_COMMAND_QUERY) ec_dbg_evt("Command(%s) completed by hardware", acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); - wakeup = true; } - } else - goto err; - } else if (t->wlen == t->wi && - (status & ACPI_EC_FLAG_IBF) == 0) { + } else if (interrupt && !(status & ACPI_EC_FLAG_SCI)) { + acpi_ec_spurious_interrupt(ec, t); + } + } else if (t->wlen == t->wi && !(status & ACPI_EC_FLAG_IBF)) { ec_transaction_transition(ec, ACPI_EC_COMMAND_COMPLETE); wakeup = true; } - goto out; } else if (!(status & ACPI_EC_FLAG_IBF)) { acpi_ec_write_cmd(ec, t->command); ec_transaction_transition(ec, ACPI_EC_COMMAND_POLL); - goto out; - } -err: - /* - * If SCI bit is set, then don't think it's a false IRQ - * otherwise will take a not handled IRQ as a false one. - */ - if (!(status & ACPI_EC_FLAG_SCI)) { - if (in_interrupt() && t) { - if (t->irq_count < ec_storm_threshold) - ++t->irq_count; - /* Allow triggering on 0 threshold */ - if (t->irq_count == ec_storm_threshold) - acpi_ec_mask_events(ec); - } } + out: if (status & ACPI_EC_FLAG_SCI) acpi_ec_submit_query(ec); - if (wakeup && in_interrupt()) + + if (wakeup && interrupt) wake_up(&ec->wait); } @@ -767,7 +754,7 @@ static int ec_poll(struct acpi_ec *ec) if (!ec_guard(ec)) return 0; spin_lock_irqsave(&ec->lock, flags); - advance_transaction(ec); + advance_transaction(ec, false); spin_unlock_irqrestore(&ec->lock, flags); } while (time_before(jiffies, delay)); pr_debug("controller reset, restart transaction\n"); @@ -1216,7 +1203,7 @@ static void acpi_ec_check_event(struct acpi_ec *ec) * taking care of it. */ if (!ec->curr) - advance_transaction(ec); + advance_transaction(ec, false); spin_unlock_irqrestore(&ec->lock, flags); } } @@ -1259,7 +1246,7 @@ static void acpi_ec_handle_interrupt(struct acpi_ec *ec) unsigned long flags; spin_lock_irqsave(&ec->lock, flags); - advance_transaction(ec); + advance_transaction(ec, true); spin_unlock_irqrestore(&ec->lock, flags); } diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index e3638bafb941..cb229e24c563 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/pci_root.c b/drivers/acpi/pci_root.c index c12b5fb3e8fb..0bf072cef6cf 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -722,9 +722,7 @@ static void acpi_pci_root_validate_resources(struct device *dev, * our resources no longer match the ACPI _CRS, but * the kernel resource tree doesn't allow overlaps. */ - if (resource_overlaps(res1, res2)) { - res2->start = min(res1->start, res2->start); - res2->end = max(res1->end, res2->end); + if (resource_union(res1, res2, res2)) { dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n", res2, res1); free = true; diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 8048da85b7e0..189a0d4c6d06 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/processor_idle.c b/drivers/acpi/processor_idle.c index f66236cff69b..d93e400940a3 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -31,7 +31,6 @@ #include <asm/apic.h> #endif -#define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_idle"); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index b04a68950ff1..0dcedd652807 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -22,7 +22,6 @@ #define PREFIX "ACPI: " -#define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_perflib"); @@ -616,7 +615,6 @@ int acpi_processor_preregister_performance( continue; pr->performance = per_cpu_ptr(performance, i); - cpumask_set_cpu(i, pr->performance->shared_cpu_map); pdomain = &(pr->performance->domain_info); if (acpi_processor_get_psd(pr->handle, pdomain)) { retval = -EINVAL; diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 6c7d05b37c98..677a132be242 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -19,8 +19,6 @@ #define PREFIX "ACPI: " -#define ACPI_PROCESSOR_CLASS "processor" - #ifdef CONFIG_CPU_FREQ /* If a passive cooling situation is detected, primarily CPUfreq is used, as it diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index a0bd56ece3ff..b1876534324b 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -22,7 +22,6 @@ #define PREFIX "ACPI: " -#define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_throttling"); diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 58203193417e..20a7892c6d3f 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -534,7 +534,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, ret = c->preproc(ares, c->preproc_data); if (ret < 0) { c->error = ret; - return AE_CTRL_TERMINATE; + return AE_ABORT_METHOD; } else if (ret > 0) { return AE_OK; } diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index e6d9f4de2800..3b0b6dd34914 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -711,26 +711,4 @@ static struct acpi_driver acpi_sbs_driver = { }, .drv.pm = &acpi_sbs_pm, }; - -static int __init acpi_sbs_init(void) -{ - int result = 0; - - if (acpi_disabled) - return -ENODEV; - - result = acpi_bus_register_driver(&acpi_sbs_driver); - if (result < 0) - return -ENODEV; - - return 0; -} - -static void __exit acpi_sbs_exit(void) -{ - acpi_bus_unregister_driver(&acpi_sbs_driver); - return; -} - -module_init(acpi_sbs_init); -module_exit(acpi_sbs_exit); +module_acpi_driver(acpi_sbs_driver); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 519963bcc047..a1b226eb2ce2 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) @@ -719,6 +719,42 @@ int acpi_device_add(struct acpi_device *device, /* -------------------------------------------------------------------------- Device Enumeration -------------------------------------------------------------------------- */ +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; + + 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_ids[] = { + "PNP0D80", /* Windows-compatible System Power Management Controller */ + NULL +}; + static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) { struct acpi_device *device = NULL; @@ -1236,10 +1272,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; @@ -1250,8 +1284,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; @@ -1276,8 +1309,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. @@ -1583,7 +1614,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; @@ -1592,7 +1624,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, fwnode_init(&device->fwnode, &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; @@ -1620,14 +1652,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. @@ -1833,13 +1871,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_ids(info, acpi_ignore_dep_ids); kfree(info); if (skip) @@ -1849,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); @@ -2026,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; diff --git a/drivers/acpi/tiny-power-button.c b/drivers/acpi/tiny-power-button.c index 420e61b8eaae..a19f0e4e69f7 100644 --- a/drivers/acpi/tiny-power-button.c +++ b/drivers/acpi/tiny-power-button.c @@ -40,6 +40,4 @@ static struct acpi_driver acpi_tiny_power_button_driver = { }, }; -module_driver(acpi_tiny_power_button_driver, - acpi_bus_register_driver, - acpi_bus_unregister_driver); +module_acpi_driver(acpi_tiny_power_button_driver); diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 4f5463b2a217..811d298637cb 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -140,6 +140,13 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, + .ident = "GIGABYTE GB-BXBT-2807", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), + }, + }, + { .ident = "Sony VPCEH3U1E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |