aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher')
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c23
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c6
-rw-r--r--drivers/acpi/dispatcher/dswload.c41
3 files changed, 56 insertions, 14 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 }
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index b47c54fad86d..459160ff9058 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -336,7 +336,7 @@ acpi_ds_method_data_set_value(u16 opcode,
336 * Increment ref count so object can't be deleted while installed. 336 * Increment ref count so object can't be deleted while installed.
337 * NOTE: We do not copy the object in order to preserve the call by 337 * NOTE: We do not copy the object in order to preserve the call by
338 * reference semantics of ACPI Control Method invocation. 338 * reference semantics of ACPI Control Method invocation.
339 * (See ACPI specification 2.0_c) 339 * (See ACPI Specification 2.0_c)
340 */ 340 */
341 acpi_ut_add_reference(object); 341 acpi_ut_add_reference(object);
342 342
@@ -351,7 +351,7 @@ acpi_ds_method_data_set_value(u16 opcode,
351 * FUNCTION: acpi_ds_method_data_get_value 351 * FUNCTION: acpi_ds_method_data_get_value
352 * 352 *
353 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 353 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
354 * Index - which local_var or argument to get 354 * Index - Which local_var or argument to get
355 * walk_state - Current walk state object 355 * walk_state - Current walk state object
356 * dest_desc - Where Arg or Local value is returned 356 * dest_desc - Where Arg or Local value is returned
357 * 357 *
@@ -459,7 +459,7 @@ acpi_ds_method_data_get_value(u16 opcode,
459 * FUNCTION: acpi_ds_method_data_delete_value 459 * FUNCTION: acpi_ds_method_data_delete_value
460 * 460 *
461 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP 461 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
462 * Index - which local_var or argument to delete 462 * Index - Which local_var or argument to delete
463 * walk_state - Current walk state object 463 * walk_state - Current walk state object
464 * 464 *
465 * RETURN: None 465 * RETURN: None
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index a8deb700cf33..35074399c617 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -178,12 +178,12 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
178 * Target of Scope() not found. Generate an External for it, and 178 * Target of Scope() not found. Generate an External for it, and
179 * insert the name into the namespace. 179 * insert the name into the namespace.
180 */ 180 */
181 acpi_dm_add_to_external_list(path); 181 acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0);
182 status = 182 status =
183 acpi_ns_lookup(walk_state->scope_info, path, 183 acpi_ns_lookup(walk_state->scope_info, path,
184 object_type, ACPI_IMODE_LOAD_PASS1, 184 object_type, ACPI_IMODE_LOAD_PASS1,
185 ACPI_NS_SEARCH_PARENT, walk_state, 185 ACPI_NS_SEARCH_PARENT, walk_state,
186 &(node)); 186 &node);
187 } 187 }
188#endif 188#endif
189 if (ACPI_FAILURE(status)) { 189 if (ACPI_FAILURE(status)) {
@@ -301,10 +301,41 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
301 status = 301 status =
302 acpi_ns_lookup(walk_state->scope_info, path, object_type, 302 acpi_ns_lookup(walk_state->scope_info, path, object_type,
303 ACPI_IMODE_LOAD_PASS1, flags, walk_state, 303 ACPI_IMODE_LOAD_PASS1, flags, walk_state,
304 &(node)); 304 &node);
305 if (ACPI_FAILURE(status)) { 305 if (ACPI_FAILURE(status)) {
306 ACPI_ERROR_NAMESPACE(path, status); 306 if (status == AE_ALREADY_EXISTS) {
307 return_ACPI_STATUS(status); 307
308 /* The name already exists in this scope */
309
310 if (node->flags & ANOBJ_IS_EXTERNAL) {
311 /*
312 * Allow one create on an object or segment that was
313 * previously declared External
314 */
315 node->flags &= ~ANOBJ_IS_EXTERNAL;
316 node->type = (u8) object_type;
317
318 /* Just retyped a node, probably will need to open a scope */
319
320 if (acpi_ns_opens_scope(object_type)) {
321 status =
322 acpi_ds_scope_stack_push
323 (node, object_type,
324 walk_state);
325 if (ACPI_FAILURE(status)) {
326 return_ACPI_STATUS
327 (status);
328 }
329 }
330 status = AE_OK;
331 }
332 }
333
334 if (ACPI_FAILURE(status)) {
335
336 ACPI_ERROR_NAMESPACE(path, status);
337 return_ACPI_STATUS(status);
338 }
308 } 339 }
309 break; 340 break;
310 } 341 }