diff options
Diffstat (limited to 'drivers/acpi/dispatcher/dsmethod.c')
-rw-r--r-- | drivers/acpi/dispatcher/dsmethod.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 651f2b68531b..e348db0e541e 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -385,6 +385,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, | |||
385 | union acpi_operand_object *return_desc) | 385 | union acpi_operand_object *return_desc) |
386 | { | 386 | { |
387 | acpi_status status; | 387 | acpi_status status; |
388 | int same_as_implicit_return; | ||
388 | 389 | ||
389 | ACPI_FUNCTION_TRACE_PTR(ds_restart_control_method, walk_state); | 390 | ACPI_FUNCTION_TRACE_PTR(ds_restart_control_method, walk_state); |
390 | 391 | ||
@@ -402,6 +403,11 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, | |||
402 | 403 | ||
403 | if (return_desc) { | 404 | if (return_desc) { |
404 | 405 | ||
406 | /* Is the implicit return object the same as the return desc? */ | ||
407 | |||
408 | same_as_implicit_return = | ||
409 | (walk_state->implicit_return_obj == return_desc); | ||
410 | |||
405 | /* Are we actually going to use the return value? */ | 411 | /* Are we actually going to use the return value? */ |
406 | 412 | ||
407 | if (walk_state->return_used) { | 413 | if (walk_state->return_used) { |
@@ -422,18 +428,23 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, | |||
422 | } | 428 | } |
423 | 429 | ||
424 | /* | 430 | /* |
425 | * The following code is the | 431 | * The following code is the optional support for the so-called |
426 | * optional support for a so-called "implicit return". Some AML code | 432 | * "implicit return". Some AML code assumes that the last value of the |
427 | * assumes that the last value of the method is "implicitly" returned | 433 | * method is "implicitly" returned to the caller, in the absence of an |
428 | * to the caller. Just save the last result as the return value. | 434 | * explicit return value. |
435 | * | ||
436 | * Just save the last result of the method as the return value. | ||
437 | * | ||
429 | * NOTE: this is optional because the ASL language does not actually | 438 | * NOTE: this is optional because the ASL language does not actually |
430 | * support this behavior. | 439 | * support this behavior. |
431 | */ | 440 | */ |
432 | else if (!acpi_ds_do_implicit_return | 441 | else if (!acpi_ds_do_implicit_return |
433 | (return_desc, walk_state, FALSE)) { | 442 | (return_desc, walk_state, FALSE) |
443 | || same_as_implicit_return) { | ||
434 | /* | 444 | /* |
435 | * Delete the return value if it will not be used by the | 445 | * Delete the return value if it will not be used by the |
436 | * calling method | 446 | * calling method or remove one reference if the explicit return |
447 | * is the same as the implicit return value. | ||
437 | */ | 448 | */ |
438 | acpi_ut_remove_reference(return_desc); | 449 | acpi_ut_remove_reference(return_desc); |
439 | } | 450 | } |