summaryrefslogtreecommitdiff
path: root/drivers/acpi/acpica/dspkginit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 10:38:46 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 10:38:46 -0700
commitbe5537542743f72c7cedddd145c17cf7706baa23 (patch)
tree1eaa950ff08d3e57cf5db6b7d6ddef229ed95a54 /drivers/acpi/acpica/dspkginit.c
parent642e7fd23353e22290e3d51719fcb658dc252342 (diff)
parent49076b2c64a25d21d5d2870dc9caa4aa562b8609 (diff)
Merge tag 'acpi-4.17-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 follow upstream revision 20180313 which includes fixes related to the so-called module-level AML (mostly "if" type of statements outside of any methods) that should improve the handling of systems that load alternative SSDTs depending on the current configuration, for example, and event handling fixes related to disabling and enabling GPEs on system startup and on suspend/resume. Moreover, the ACPICA license boilerplate is replaced with SPDX license IDs which alone reduces the number of lines of ACPICA code in the kernel quite a bit. Also added is a new driver for the generic ACPI Time and Alarm Device (TAD). At the moment it only handles the most basic capabilities of the TAD, however. In addition to that the ACPI battery driver is improved to handle battery thresholds on ThinkPads, among other things, some bugs are fixed, a new backlight quirk is added and some documentation is updated. Specifics: - Update the in-kernel ACPICA code to upstream revision 20180313 including: * Module-level AML code handling fixes and simplifications (Bob Moore, Erik Schmauss). * Fixes and cleanups related to messaging (Bob Moore). * Events handling fixes related to disabling and enabling GPEs (Erik Schmauss). * Introduction of SPDX license identifiers and removal of license boilerplate in multiple files (Erik Schmauss). * Assorted fixes and cleanups (Bob Moore, Erik Schmauss, Hans de Goede, Seunghun Han). - Add new basic driver for the ACPI Time and Alarm Device (Rafael Wysocki). - Modify the ACPI battery driver to support battery thresholds on Lenovo ThinkPads (Ognjen Galic, Colin Ian King). - Avoid reporting battery capacity over 100 in the ACPI battery driver in some cases (Laszlo Toth). - Make the kernel recognize an OEM _OSI string from Dell to avoid power management issues with NVidia GPUs in Dell platforms (Alex Hung). - Make the PCI IRQ management code handle missing _PRS cleanly (Alex Hung). - Fix uevent notifications related to device hotplut (Lee, Chun-Yi). - Prevent the ACPI PAD driver from leaking memory (Lenny Szubowicz). - Update the ACPI CPPC library code to include subspace IDs in the kernel messages logged by it (George Cherian). - Add backlight quirk for Samsung 670Z5E (Hans de Goede). - Add the NFIT and HMAT tables to the list of ACPI tables that can be overridden via initrd (Dan Williams). - Fix and clean up some ACPI documentation and Kconfig help language (Aishwarya Pant, Randy Dunlap). - Replace license boilerplate with an SPDX license ID in the ACPI PMIC operation region handling code (Rajmohan Mani)" * tag 'acpi-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (39 commits) ACPI: acpi_pad: Fix memory leak in power saving threads ACPI / video: Add quirk to force acpi-video backlight on Samsung 670Z5E ACPI: Add Time and Alarm Device (TAD) driver ACPI / scan: Send change uevent with offine environmental data ACPI / Kconfig: Update ACPI_PROCFS_POWER help text ACPI / OSI: Add OEM _OSI strings to disable NVidia RTD3 ACPICA: Update version to 20180313 ACPICA: Cleanup/simplify module-level code support ACPICA: Events: add a return on failure from acpi_hw_register_read ACPICA: adding SPDX headers ACPICA: Rename a global for clarity, no functional change ACPICA: macros: fix ACPI_ERROR_NAMESPACE macro ACPICA: Change a compile-time option to a runtime option ACPICA: Remove calling of _STA from acpi_get_object_info() ACPICA: AML Debug Object: Don't ignore output of zero-length strings ACPICA: Fix memory leak on unusual memory leak ACPICA: Events: Dispatch GPEs after enabling for the first time ACPICA: Events: Add parallel GPE handling support to fix potential redundant _Exx evaluations ACPICA: Events: Stop unconditionally clearing ACPI IRQs during suspend/resume ACPICA: acpi: acpica: fix acpi operand cache leak in nseval.c ...
Diffstat (limited to 'drivers/acpi/acpica/dspkginit.c')
-rw-r--r--drivers/acpi/acpica/dspkginit.c204
1 files changed, 104 insertions, 100 deletions
diff --git a/drivers/acpi/acpica/dspkginit.c b/drivers/acpi/acpica/dspkginit.c
index 902bee78036c..d703a5594a02 100644
--- a/drivers/acpi/acpica/dspkginit.c
+++ b/drivers/acpi/acpica/dspkginit.c
@@ -1,45 +1,11 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
*
* Module Name: dspkginit - Completion of deferred package initialization
*
- *****************************************************************************/
-
-/*
* Copyright (C) 2000 - 2018, Intel Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- * substantially similar to the "NO WARRANTY" disclaimer below
- * ("Disclaimer") and any redistribution must be conditioned upon
- * including a substantially similar Disclaimer requirement for further
- * binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- * of any contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
*
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- */
+ *****************************************************************************/
#include <acpi/acpi.h>
#include "accommon.h"
@@ -47,6 +13,7 @@
#include "amlcode.h"
#include "acdispat.h"
#include "acinterp.h"
+#include "acparser.h"
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("dspkginit")
@@ -94,12 +61,19 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
union acpi_parse_object *parent;
union acpi_operand_object *obj_desc = NULL;
acpi_status status = AE_OK;
+ u8 module_level_code = FALSE;
u16 reference_count;
u32 index;
u32 i;
ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
+ /* Check if we are executing module level code */
+
+ if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
+ module_level_code = TRUE;
+ }
+
/* Find the parent of a possibly nested package */
parent = op->common.parent;
@@ -130,24 +104,44 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
/*
* Allocate the element array (array of pointers to the individual
- * objects) based on the num_elements parameter. Add an extra pointer slot
- * so that the list is always null terminated.
+ * objects) if necessary. the count is based on the num_elements
+ * parameter. Add an extra pointer slot so that the list is always
+ * null terminated.
*/
- obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
- element_count +
- 1) * sizeof(void *));
-
if (!obj_desc->package.elements) {
- acpi_ut_delete_object_desc(obj_desc);
- return_ACPI_STATUS(AE_NO_MEMORY);
+ obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
+ element_count
+ +
+ 1) *
+ sizeof(void
+ *));
+
+ if (!obj_desc->package.elements) {
+ acpi_ut_delete_object_desc(obj_desc);
+ return_ACPI_STATUS(AE_NO_MEMORY);
+ }
+
+ obj_desc->package.count = element_count;
}
- obj_desc->package.count = element_count;
+ /* First arg is element count. Second arg begins the initializer list */
+
arg = op->common.value.arg;
arg = arg->common.next;
- if (arg) {
- obj_desc->package.flags |= AOPOBJ_DATA_VALID;
+ /*
+ * If we are executing module-level code, we will defer the
+ * full resolution of the package elements in order to support
+ * forward references from the elements. This provides
+ * compatibility with other ACPI implementations.
+ */
+ if (module_level_code) {
+ obj_desc->package.aml_start = walk_state->aml;
+ obj_desc->package.aml_length = 0;
+
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
+ "%s: Deferring resolution of Package elements\n",
+ ACPI_GET_FUNCTION_NAME));
}
/*
@@ -187,15 +181,19 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
"****DS namepath not found"));
}
- /*
- * Initialize this package element. This function handles the
- * resolution of named references within the package.
- */
- acpi_ds_init_package_element(0,
- obj_desc->package.
- elements[i], NULL,
- &obj_desc->package.
- elements[i]);
+ if (!module_level_code) {
+ /*
+ * Initialize this package element. This function handles the
+ * resolution of named references within the package.
+ * Forward references from module-level code are deferred
+ * until all ACPI tables are loaded.
+ */
+ acpi_ds_init_package_element(0,
+ obj_desc->package.
+ elements[i], NULL,
+ &obj_desc->package.
+ elements[i]);
+ }
}
if (*obj_desc_ptr) {
@@ -265,15 +263,21 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
* num_elements count.
*
* Note: this is not an error, the package is padded out
- * with NULLs.
+ * with NULLs as per the ACPI specification.
*/
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Package List length (%u) smaller than NumElements "
- "count (%u), padded with null elements\n",
- i, element_count));
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
+ "%s: Package List length (%u) smaller than NumElements "
+ "count (%u), padded with null elements\n",
+ ACPI_GET_FUNCTION_NAME, i,
+ element_count));
+ }
+
+ /* Module-level packages will be resolved later */
+
+ if (!module_level_code) {
+ obj_desc->package.flags |= AOPOBJ_DATA_VALID;
}
- obj_desc->package.flags |= AOPOBJ_DATA_VALID;
op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
return_ACPI_STATUS(status);
}
@@ -351,11 +355,12 @@ static void
acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
{
acpi_status status;
+ acpi_status status2;
union acpi_generic_state scope_info;
union acpi_operand_object *element = *element_ptr;
struct acpi_namespace_node *resolved_node;
struct acpi_namespace_node *original_node;
- char *external_path = NULL;
+ char *external_path = "";
acpi_object_type type;
ACPI_FUNCTION_TRACE(ds_resolve_package_element);
@@ -363,6 +368,10 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
/* Check if reference element is already resolved */
if (element->reference.resolved) {
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
+ "%s: Package element is already resolved\n",
+ ACPI_GET_FUNCTION_NAME));
+
return_VOID;
}
@@ -370,20 +379,46 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
scope_info.scope.node = element->reference.node; /* Prefix node */
- status = acpi_ns_lookup(&scope_info, (char *)element->reference.aml, /* Pointer to AML path */
+ status = acpi_ns_lookup(&scope_info, (char *)element->reference.aml,
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
NULL, &resolved_node);
if (ACPI_FAILURE(status)) {
- status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
- (char *)element->reference.
- aml, NULL, &external_path);
+ if ((status == AE_NOT_FOUND)
+ && acpi_gbl_ignore_package_resolution_errors) {
+ /*
+ * Optionally be silent about the NOT_FOUND case for the referenced
+ * name. Although this is potentially a serious problem,
+ * it can generate a lot of noise/errors on platforms whose
+ * firmware carries around a bunch of unused Package objects.
+ * To disable these errors, set this global to TRUE:
+ * acpi_gbl_ignore_package_resolution_errors
+ *
+ * If the AML actually tries to use such a package, the unresolved
+ * element(s) will be replaced with NULL elements.
+ */
+
+ /* Referenced name not found, set the element to NULL */
+
+ acpi_ut_remove_reference(*element_ptr);
+ *element_ptr = NULL;
+ return_VOID;
+ }
+
+ status2 = acpi_ns_externalize_name(ACPI_UINT32_MAX,
+ (char *)element->reference.
+ aml, NULL, &external_path);
ACPI_EXCEPTION((AE_INFO, status,
- "Could not find/resolve named package element: %s",
+ "While resolving a named reference package element - %s",
external_path));
+ if (ACPI_SUCCESS(status2)) {
+ ACPI_FREE(external_path);
+ }
+
+ /* Could not resolve name, set the element to NULL */
- ACPI_FREE(external_path);
+ acpi_ut_remove_reference(*element_ptr);
*element_ptr = NULL;
return_VOID;
} else if (resolved_node->type == ACPI_TYPE_ANY) {
@@ -397,23 +432,6 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
*element_ptr = NULL;
return_VOID;
}
-#if 0
- else if (resolved_node->flags & ANOBJ_TEMPORARY) {
- /*
- * A temporary node found here indicates that the reference is
- * to a node that was created within this method. We are not
- * going to allow it (especially if the package is returned
- * from the method) -- the temporary node will be deleted out
- * from under the method. (05/2017).
- */
- ACPI_ERROR((AE_INFO,
- "Package element refers to a temporary name [%4.4s], "
- "inserting a NULL element",
- resolved_node->name.ascii));
- *element_ptr = NULL;
- return_VOID;
- }
-#endif
/*
* Special handling for Alias objects. We need resolved_node to point
@@ -449,20 +467,6 @@ acpi_ds_resolve_package_element(union acpi_operand_object **element_ptr)
if (ACPI_FAILURE(status)) {
return_VOID;
}
-#if 0
-/* TBD - alias support */
- /*
- * Special handling for Alias objects. We need to setup the type
- * and the Op->Common.Node to point to the Alias target. Note,
- * Alias has at most one level of indirection internally.
- */
- type = op->common.node->type;
- if (type == ACPI_TYPE_LOCAL_ALIAS) {
- type = obj_desc->common.type;
- op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node,
- op->common.node->object);
- }
-#endif
switch (type) {
/*