aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nseval.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nseval.c')
-rw-r--r--drivers/acpi/acpica/nseval.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 846d1132feb1..f771e978c403 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -366,33 +366,49 @@ static void
366acpi_ns_exec_module_code(union acpi_operand_object *method_obj, 366acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
367 struct acpi_evaluate_info *info) 367 struct acpi_evaluate_info *info)
368{ 368{
369 union acpi_operand_object *root_obj; 369 union acpi_operand_object *parent_obj;
370 struct acpi_namespace_node *parent_node;
371 acpi_object_type type;
370 acpi_status status; 372 acpi_status status;
371 373
372 ACPI_FUNCTION_TRACE(ns_exec_module_code); 374 ACPI_FUNCTION_TRACE(ns_exec_module_code);
373 375
376 /*
377 * Get the parent node. We cheat by using the next_object field
378 * of the method object descriptor.
379 */
380 parent_node = ACPI_CAST_PTR(struct acpi_namespace_node,
381 method_obj->method.next_object);
382 type = acpi_ns_get_type(parent_node);
383
384 /* Must clear next_object (acpi_ns_attach_object needs the field) */
385
386 method_obj->method.next_object = NULL;
387
374 /* Initialize the evaluation information block */ 388 /* Initialize the evaluation information block */
375 389
376 ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); 390 ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
377 info->prefix_node = acpi_gbl_root_node; 391 info->prefix_node = parent_node;
378 392
379 /* 393 /*
380 * Get the currently attached root object. Add a reference, because the 394 * Get the currently attached parent object. Add a reference, because the
381 * ref count will be decreased when the method object is installed to 395 * ref count will be decreased when the method object is installed to
382 * the root node. 396 * the parent node.
383 */ 397 */
384 root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node); 398 parent_obj = acpi_ns_get_attached_object(parent_node);
385 acpi_ut_add_reference(root_obj); 399 if (parent_obj) {
400 acpi_ut_add_reference(parent_obj);
401 }
386 402
387 /* Install the method (module-level code) in the root node */ 403 /* Install the method (module-level code) in the parent node */
388 404
389 status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj, 405 status = acpi_ns_attach_object(parent_node, method_obj,
390 ACPI_TYPE_METHOD); 406 ACPI_TYPE_METHOD);
391 if (ACPI_FAILURE(status)) { 407 if (ACPI_FAILURE(status)) {
392 goto exit; 408 goto exit;
393 } 409 }
394 410
395 /* Execute the root node as a control method */ 411 /* Execute the parent node as a control method */
396 412
397 status = acpi_ns_evaluate(info); 413 status = acpi_ns_evaluate(info);
398 414
@@ -401,15 +417,19 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
401 417
402 /* Detach the temporary method object */ 418 /* Detach the temporary method object */
403 419
404 acpi_ns_detach_object(acpi_gbl_root_node); 420 acpi_ns_detach_object(parent_node);
405 421
406 /* Restore the original root object */ 422 /* Restore the original parent object */
407 423
408 status = 424 if (parent_obj) {
409 acpi_ns_attach_object(acpi_gbl_root_node, root_obj, 425 status = acpi_ns_attach_object(parent_node, parent_obj, type);
410 ACPI_TYPE_DEVICE); 426 } else {
427 parent_node->type = (u8)type;
428 }
411 429
412 exit: 430 exit:
413 acpi_ut_remove_reference(root_obj); 431 if (parent_obj) {
432 acpi_ut_remove_reference(parent_obj);
433 }
414 return_VOID; 434 return_VOID;
415} 435}