Browse Source

Merge tag 'acpi-4.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI fix from Rafael Wysocki:
 "Fix an ACPICA regression introduced in this cycle and related to the
  handling of package objects loaded by the Load and loadTable AML
  operators that are not initialized properly after recent changes (Bob
  Moore)"

* tag 'acpi-4.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPICA: Add deferred package support for the Load and loadTable operators
Linus Torvalds 7 years ago
parent
commit
d315482168
3 changed files with 74 additions and 20 deletions
  1. 4 0
      drivers/acpi/acpica/acnamesp.h
  2. 14 0
      drivers/acpi/acpica/exconfig.c
  3. 56 20
      drivers/acpi/acpica/nsinit.c

+ 4 - 0
drivers/acpi/acpica/acnamesp.h

@@ -56,6 +56,10 @@ acpi_status acpi_ns_initialize_objects(void);
 
 
 acpi_status acpi_ns_initialize_devices(u32 flags);
 acpi_status acpi_ns_initialize_devices(u32 flags);
 
 
+acpi_status
+acpi_ns_init_one_package(acpi_handle obj_handle,
+			 u32 level, void *context, void **return_value);
+
 /*
 /*
  * nsload -  Namespace loading
  * nsload -  Namespace loading
  */
  */

+ 14 - 0
drivers/acpi/acpica/exconfig.c

@@ -174,6 +174,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 		return_ACPI_STATUS(status);
 		return_ACPI_STATUS(status);
 	}
 	}
 
 
+	/* Complete the initialization/resolution of package objects */
+
+	status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, ACPI_ROOT_OBJECT,
+					ACPI_UINT32_MAX, 0,
+					acpi_ns_init_one_package, NULL, NULL,
+					NULL);
+
 	/* Parameter Data (optional) */
 	/* Parameter Data (optional) */
 
 
 	if (parameter_node) {
 	if (parameter_node) {
@@ -430,6 +437,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 		return_ACPI_STATUS(status);
 		return_ACPI_STATUS(status);
 	}
 	}
 
 
+	/* Complete the initialization/resolution of package objects */
+
+	status = acpi_ns_walk_namespace(ACPI_TYPE_PACKAGE, ACPI_ROOT_OBJECT,
+					ACPI_UINT32_MAX, 0,
+					acpi_ns_init_one_package, NULL, NULL,
+					NULL);
+
 	/* Store the ddb_handle into the Target operand */
 	/* Store the ddb_handle into the Target operand */
 
 
 	status = acpi_ex_store(ddb_handle, target, walk_state);
 	status = acpi_ex_store(ddb_handle, target, walk_state);

+ 56 - 20
drivers/acpi/acpica/nsinit.c

@@ -240,6 +240,58 @@ error_exit:
 	return_ACPI_STATUS(status);
 	return_ACPI_STATUS(status);
 }
 }
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_init_one_package
+ *
+ * PARAMETERS:  obj_handle      - Node
+ *              level           - Current nesting level
+ *              context         - Not used
+ *              return_value    - Not used
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every package
+ *              within the namespace. Used during dynamic load of an SSDT.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_init_one_package(acpi_handle obj_handle,
+			 u32 level, void *context, void **return_value)
+{
+	acpi_status status;
+	union acpi_operand_object *obj_desc;
+	struct acpi_namespace_node *node =
+	    (struct acpi_namespace_node *)obj_handle;
+
+	obj_desc = acpi_ns_get_attached_object(node);
+	if (!obj_desc) {
+		return (AE_OK);
+	}
+
+	/* Exit if package is already initialized */
+
+	if (obj_desc->package.flags & AOPOBJ_DATA_VALID) {
+		return (AE_OK);
+	}
+
+	status = acpi_ds_get_package_arguments(obj_desc);
+	if (ACPI_FAILURE(status)) {
+		return (AE_OK);
+	}
+
+	status =
+	    acpi_ut_walk_package_tree(obj_desc, NULL,
+				      acpi_ds_init_package_element, NULL);
+	if (ACPI_FAILURE(status)) {
+		return (AE_OK);
+	}
+
+	obj_desc->package.flags |= AOPOBJ_DATA_VALID;
+	return (AE_OK);
+}
+
 /*******************************************************************************
 /*******************************************************************************
  *
  *
  * FUNCTION:    acpi_ns_init_one_object
  * FUNCTION:    acpi_ns_init_one_object
@@ -360,27 +412,11 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
 
 
 	case ACPI_TYPE_PACKAGE:
 	case ACPI_TYPE_PACKAGE:
 
 
-		info->package_init++;
-		status = acpi_ds_get_package_arguments(obj_desc);
-		if (ACPI_FAILURE(status)) {
-			break;
-		}
-
-		ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
-				      "%s: Completing resolution of Package elements\n",
-				      ACPI_GET_FUNCTION_NAME));
+		/* Complete the initialization/resolution of the package object */
 
 
-		/*
-		 * Resolve all named references in package objects (and all
-		 * sub-packages). This action has been deferred until the entire
-		 * namespace has been loaded, in order to support external and
-		 * forward references from individual package elements (05/2017).
-		 */
-		status = acpi_ut_walk_package_tree(obj_desc, NULL,
-						   acpi_ds_init_package_element,
-						   NULL);
-
-		obj_desc->package.flags |= AOPOBJ_DATA_VALID;
+		info->package_init++;
+		status =
+		    acpi_ns_init_one_package(obj_handle, level, NULL, NULL);
 		break;
 		break;
 
 
 	default:
 	default: