diff options
Diffstat (limited to 'drivers/acpi/acpica/nseval.c')
-rw-r--r-- | drivers/acpi/acpica/nseval.c | 50 |
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 | |||
366 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | 366 | acpi_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 | } |