aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/hwxface.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2013-01-25 00:41:00 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-25 07:30:47 -0500
commit48ffb94f9e6f9b11c26884f26199e3d51bb22e54 (patch)
tree6764c971ddf5527719273e491c24655581019f0f /drivers/acpi/acpica/hwxface.c
parent25f044e64568dd83de34c16c837a96bbb2b0cecb (diff)
ACPICA: AcpiGetSleepTypeData: Allow \_Sx to return either 1 or 2 integers
Although the ACPI spec defines the \_Sx objects to return a package containing one integer, most BIOS code returns two integers and the previous code reflects that. However, we also need to support BIOS code that actually implements to the ACPI spec, and this change implements this. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/hwxface.c')
-rw-r--r--drivers/acpi/acpica/hwxface.c125
1 files changed, 74 insertions, 51 deletions
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index a4bac0881374..04c2e16f2c0a 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -440,17 +440,41 @@ ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
440 * *sleep_type_a - Where SLP_TYPa is returned 440 * *sleep_type_a - Where SLP_TYPa is returned
441 * *sleep_type_b - Where SLP_TYPb is returned 441 * *sleep_type_b - Where SLP_TYPb is returned
442 * 442 *
443 * RETURN: status - ACPI status 443 * RETURN: Status
444 *
445 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
446 * sleep state via the appropriate \_Sx object.
447 *
448 * The sleep state package returned from the corresponding \_Sx_ object
449 * must contain at least one integer.
450 *
451 * March 2005:
452 * Added support for a package that contains two integers. This
453 * goes against the ACPI specification which defines this object as a
454 * package with one encoded DWORD integer. However, existing practice
455 * by many BIOS vendors is to return a package with 2 or more integer
456 * elements, at least one per sleep type (A/B).
444 * 457 *
445 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep 458 * January 2013:
446 * state. 459 * Therefore, we must be prepared to accept a package with either a
460 * single integer or multiple integers.
461 *
462 * The single integer DWORD format is as follows:
463 * BYTE 0 - Value for the PM1A SLP_TYP register
464 * BYTE 1 - Value for the PM1B SLP_TYP register
465 * BYTE 2-3 - Reserved
466 *
467 * The dual integer format is as follows:
468 * Integer 0 - Value for the PM1A SLP_TYP register
469 * Integer 1 - Value for the PM1A SLP_TYP register
447 * 470 *
448 ******************************************************************************/ 471 ******************************************************************************/
449acpi_status 472acpi_status
450acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) 473acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
451{ 474{
452 acpi_status status = AE_OK; 475 acpi_status status;
453 struct acpi_evaluate_info *info; 476 struct acpi_evaluate_info *info;
477 union acpi_operand_object **elements;
454 478
455 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); 479 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
456 480
@@ -467,18 +491,14 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
467 return_ACPI_STATUS(AE_NO_MEMORY); 491 return_ACPI_STATUS(AE_NO_MEMORY);
468 } 492 }
469 493
494 /*
495 * Evaluate the \_Sx namespace object containing the register values
496 * for this state
497 */
470 info->pathname = 498 info->pathname =
471 ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); 499 ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
472
473 /* Evaluate the namespace object containing the values for this state */
474
475 status = acpi_ns_evaluate(info); 500 status = acpi_ns_evaluate(info);
476 if (ACPI_FAILURE(status)) { 501 if (ACPI_FAILURE(status)) {
477 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
478 "%s while evaluating SleepState [%s]\n",
479 acpi_format_exception(status),
480 info->pathname));
481
482 goto cleanup; 502 goto cleanup;
483 } 503 }
484 504
@@ -487,64 +507,67 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
487 if (!info->return_object) { 507 if (!info->return_object) {
488 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", 508 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
489 info->pathname)); 509 info->pathname));
490 status = AE_NOT_EXIST; 510 status = AE_AML_NO_RETURN_VALUE;
511 goto cleanup;
491 } 512 }
492 513
493 /* It must be of type Package */ 514 /* Return object must be of type Package */
494 515
495 else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) { 516 if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
496 ACPI_ERROR((AE_INFO, 517 ACPI_ERROR((AE_INFO,
497 "Sleep State return object is not a Package")); 518 "Sleep State return object is not a Package"));
498 status = AE_AML_OPERAND_TYPE; 519 status = AE_AML_OPERAND_TYPE;
520 goto cleanup1;
499 } 521 }
500 522
501 /* 523 /*
502 * The package must have at least two elements. NOTE (March 2005): This 524 * Any warnings about the package length or the object types have
503 * goes against the current ACPI spec which defines this object as a 525 * already been issued by the predefined name module -- there is no
504 * package with one encoded DWORD element. However, existing practice 526 * need to repeat them here.
505 * by BIOS vendors seems to be to have 2 or more elements, at least
506 * one per sleep type (A/B).
507 */ 527 */
508 else if (info->return_object->package.count < 2) { 528 elements = info->return_object->package.elements;
509 ACPI_ERROR((AE_INFO, 529 switch (info->return_object->package.count) {
510 "Sleep State return package does not have at least two elements")); 530 case 0:
511 status = AE_AML_NO_OPERAND; 531 status = AE_AML_PACKAGE_LIMIT;
512 } 532 break;
533
534 case 1:
535 if (elements[0]->common.type != ACPI_TYPE_INTEGER) {
536 status = AE_AML_OPERAND_TYPE;
537 break;
538 }
513 539
514 /* The first two elements must both be of type Integer */ 540 /* A valid _Sx_ package with one integer */
515 541
516 else if (((info->return_object->package.elements[0])->common.type 542 *sleep_type_a = (u8)elements[0]->integer.value;
517 != ACPI_TYPE_INTEGER) || 543 *sleep_type_b = (u8)(elements[0]->integer.value >> 8);
518 ((info->return_object->package.elements[1])->common.type 544 break;
519 != ACPI_TYPE_INTEGER)) {
520 ACPI_ERROR((AE_INFO,
521 "Sleep State return package elements are not both Integers "
522 "(%s, %s)",
523 acpi_ut_get_object_type_name(info->return_object->
524 package.elements[0]),
525 acpi_ut_get_object_type_name(info->return_object->
526 package.elements[1])));
527 status = AE_AML_OPERAND_TYPE;
528 } else {
529 /* Valid _Sx_ package size, type, and value */
530 545
531 *sleep_type_a = (u8) 546 case 2:
532 (info->return_object->package.elements[0])->integer.value; 547 default:
533 *sleep_type_b = (u8) 548 if ((elements[0]->common.type != ACPI_TYPE_INTEGER) ||
534 (info->return_object->package.elements[1])->integer.value; 549 (elements[1]->common.type != ACPI_TYPE_INTEGER)) {
535 } 550 status = AE_AML_OPERAND_TYPE;
551 break;
552 }
536 553
537 if (ACPI_FAILURE(status)) { 554 /* A valid _Sx_ package with two integers */
538 ACPI_EXCEPTION((AE_INFO, status, 555
539 "While evaluating SleepState [%s], bad Sleep object %p type %s", 556 *sleep_type_a = (u8)elements[0]->integer.value;
540 info->pathname, info->return_object, 557 *sleep_type_b = (u8)elements[1]->integer.value;
541 acpi_ut_get_object_type_name(info-> 558 break;
542 return_object)));
543 } 559 }
544 560
561 cleanup1:
545 acpi_ut_remove_reference(info->return_object); 562 acpi_ut_remove_reference(info->return_object);
546 563
547 cleanup: 564 cleanup:
565 if (ACPI_FAILURE(status)) {
566 ACPI_EXCEPTION((AE_INFO, status,
567 "While evaluating Sleep State [%s]",
568 info->pathname));
569 }
570
548 ACPI_FREE(info); 571 ACPI_FREE(info);
549 return_ACPI_STATUS(status); 572 return_ACPI_STATUS(status);
550} 573}