aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher')
-rw-r--r--drivers/acpi/dispatcher/dsobject.c91
1 files changed, 85 insertions, 6 deletions
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index a474ca2334d5..954ac8ce958a 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -137,6 +137,71 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
137 return_ACPI_STATUS(status); 137 return_ACPI_STATUS(status);
138 } 138 }
139 } 139 }
140
141 /* Special object resolution for elements of a package */
142
143 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
144 (op->common.parent->common.aml_opcode ==
145 AML_VAR_PACKAGE_OP)) {
146 /*
147 * Attempt to resolve the node to a value before we insert it into
148 * the package. If this is a reference to a common data type,
149 * resolve it immediately. According to the ACPI spec, package
150 * elements can only be "data objects" or method references.
151 * Attempt to resolve to an Integer, Buffer, String or Package.
152 * If cannot, return the named reference (for things like Devices,
153 * Methods, etc.) Buffer Fields and Fields will resolve to simple
154 * objects (int/buf/str/pkg).
155 *
156 * NOTE: References to things like Devices, Methods, Mutexes, etc.
157 * will remain as named references. This behavior is not described
158 * in the ACPI spec, but it appears to be an oversight.
159 */
160 obj_desc = (union acpi_operand_object *)op->common.node;
161
162 status =
163 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
164 (struct
165 acpi_namespace_node,
166 &obj_desc),
167 walk_state);
168 if (ACPI_FAILURE(status)) {
169 return_ACPI_STATUS(status);
170 }
171
172 switch (op->common.node->type) {
173 /*
174 * For these types, we need the actual node, not the subobject.
175 * However, the subobject got an extra reference count above.
176 */
177 case ACPI_TYPE_MUTEX:
178 case ACPI_TYPE_METHOD:
179 case ACPI_TYPE_POWER:
180 case ACPI_TYPE_PROCESSOR:
181 case ACPI_TYPE_EVENT:
182 case ACPI_TYPE_REGION:
183 case ACPI_TYPE_DEVICE:
184 case ACPI_TYPE_THERMAL:
185
186 obj_desc =
187 (union acpi_operand_object *)op->common.
188 node;
189 break;
190
191 default:
192 break;
193 }
194
195 /*
196 * If above resolved to an operand object, we are done. Otherwise,
197 * we have a NS node, we must create the package entry as a named
198 * reference.
199 */
200 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
201 ACPI_DESC_TYPE_NAMED) {
202 goto exit;
203 }
204 }
140 } 205 }
141 206
142 /* Create and init a new internal ACPI object */ 207 /* Create and init a new internal ACPI object */
@@ -156,6 +221,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
156 return_ACPI_STATUS(status); 221 return_ACPI_STATUS(status);
157 } 222 }
158 223
224 exit:
159 *obj_desc_ptr = obj_desc; 225 *obj_desc_ptr = obj_desc;
160 return_ACPI_STATUS(AE_OK); 226 return_ACPI_STATUS(AE_OK);
161} 227}
@@ -356,12 +422,25 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
356 arg = arg->common.next; 422 arg = arg->common.next;
357 for (i = 0; arg && (i < element_count); i++) { 423 for (i = 0; arg && (i < element_count); i++) {
358 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 424 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
359 425 if (arg->common.node->type == ACPI_TYPE_METHOD) {
360 /* This package element is already built, just get it */ 426 /*
361 427 * A method reference "looks" to the parser to be a method
362 obj_desc->package.elements[i] = 428 * invocation, so we special case it here
363 ACPI_CAST_PTR(union acpi_operand_object, 429 */
364 arg->common.node); 430 arg->common.aml_opcode = AML_INT_NAMEPATH_OP;
431 status =
432 acpi_ds_build_internal_object(walk_state,
433 arg,
434 &obj_desc->
435 package.
436 elements[i]);
437 } else {
438 /* This package element is already built, just get it */
439
440 obj_desc->package.elements[i] =
441 ACPI_CAST_PTR(union acpi_operand_object,
442 arg->common.node);
443 }
365 } else { 444 } else {
366 status = acpi_ds_build_internal_object(walk_state, arg, 445 status = acpi_ds_build_internal_object(walk_state, arg,
367 &obj_desc-> 446 &obj_desc->