aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dsfield.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher/dsfield.c')
-rw-r--r--drivers/acpi/dispatcher/dsfield.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index f049639bac35..e87f6bfbfa5c 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -281,11 +281,17 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
281 arg->common.node = info->field_node; 281 arg->common.node = info->field_node;
282 info->field_bit_length = arg->common.value.size; 282 info->field_bit_length = arg->common.value.size;
283 283
284 /* Create and initialize an object for the new Field Node */ 284 /*
285 285 * If there is no object attached to the node, this node was just created
286 status = acpi_ex_prep_field_value(info); 286 * and we need to create the field object. Otherwise, this was a lookup
287 if (ACPI_FAILURE(status)) { 287 * of an existing node and we don't want to create the field object again.
288 return_ACPI_STATUS(status); 288 */
289 if (!acpi_ns_get_attached_object
290 (info->field_node)) {
291 status = acpi_ex_prep_field_value(info);
292 if (ACPI_FAILURE(status)) {
293 return_ACPI_STATUS(status);
294 }
289 } 295 }
290 } 296 }
291 297
@@ -399,9 +405,22 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
399 union acpi_parse_object *arg = NULL; 405 union acpi_parse_object *arg = NULL;
400 struct acpi_namespace_node *node; 406 struct acpi_namespace_node *node;
401 u8 type = 0; 407 u8 type = 0;
408 u32 flags;
402 409
403 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); 410 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
404 411
412 /*
413 * During the load phase, we want to enter the name of the field into
414 * the namespace. During the execute phase (when we evaluate the bank_value
415 * operand), we want to lookup the name.
416 */
417 if (walk_state->deferred_node) {
418 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
419 } else {
420 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
421 ACPI_NS_ERROR_IF_FOUND;
422 }
423
405 switch (walk_state->opcode) { 424 switch (walk_state->opcode) {
406 case AML_FIELD_OP: 425 case AML_FIELD_OP:
407 arg = acpi_ps_get_arg(op, 2); 426 arg = acpi_ps_get_arg(op, 2);
@@ -433,10 +452,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
433 status = acpi_ns_lookup(walk_state->scope_info, 452 status = acpi_ns_lookup(walk_state->scope_info,
434 (char *)&arg->named.name, 453 (char *)&arg->named.name,
435 type, ACPI_IMODE_LOAD_PASS1, 454 type, ACPI_IMODE_LOAD_PASS1,
436 ACPI_NS_NO_UPSEARCH | 455 flags, walk_state, &node);
437 ACPI_NS_DONT_OPEN_SCOPE |
438 ACPI_NS_ERROR_IF_FOUND,
439 walk_state, &node);
440 if (ACPI_FAILURE(status)) { 456 if (ACPI_FAILURE(status)) {
441 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 457 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
442 status); 458 status);
@@ -466,7 +482,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
466 * 482 *
467 * PARAMETERS: Op - Op containing the Field definition and args 483 * PARAMETERS: Op - Op containing the Field definition and args
468 * region_node - Object for the containing Operation Region 484 * region_node - Object for the containing Operation Region
469 * ` walk_state - Current method state 485 * walk_state - Current method state
470 * 486 *
471 * RETURN: Status 487 * RETURN: Status
472 * 488 *
@@ -513,36 +529,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
513 return_ACPI_STATUS(status); 529 return_ACPI_STATUS(status);
514 } 530 }
515 531
516 /* Third arg is the bank_value */ 532 /*
517 533 * Third arg is the bank_value
518 /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ 534 * This arg is a term_arg, not a constant
519 535 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
536 */
520 arg = arg->common.next; 537 arg = arg->common.next;
521 538
522 /* Currently, only the following constants are supported */
523
524 switch (arg->common.aml_opcode) {
525 case AML_ZERO_OP:
526 info.bank_value = 0;
527 break;
528
529 case AML_ONE_OP:
530 info.bank_value = 1;
531 break;
532
533 case AML_BYTE_OP:
534 case AML_WORD_OP:
535 case AML_DWORD_OP:
536 case AML_QWORD_OP:
537 info.bank_value = (u32) arg->common.value.integer;
538 break;
539
540 default:
541 info.bank_value = 0;
542 ACPI_ERROR((AE_INFO,
543 "Non-constant BankValue for BankField is not implemented"));
544 }
545
546 /* Fourth arg is the field flags */ 539 /* Fourth arg is the field flags */
547 540
548 arg = arg->common.next; 541 arg = arg->common.next;
@@ -553,8 +546,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
553 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; 546 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
554 info.region_node = region_node; 547 info.region_node = region_node;
555 548
556 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 549 /*
550 * Use Info.data_register_node to store bank_field Op
551 * It's safe because data_register_node will never be used when create bank field
552 * We store aml_start and aml_length in the bank_field Op for late evaluation
553 * Used in acpi_ex_prep_field_value(Info)
554 *
555 * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"?
556 */
557 info.data_register_node = (struct acpi_namespace_node *)op;
557 558
559 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
558 return_ACPI_STATUS(status); 560 return_ACPI_STATUS(status);
559} 561}
560 562