diff options
| author | Janosch Machowinski <jmachowinski@gmx.de> | 2005-08-20 08:02:00 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2005-12-01 20:40:57 -0500 |
| commit | cf82478840188f8c8494c1d7a668a8ae170d0e07 (patch) | |
| tree | f4b7fdc733986d36325996bc7ce33ed7bc79e5a3 | |
| parent | 4c0335526c95d90a1d958e0059f40a5745fc7c5d (diff) | |
[ACPI] handle BIOS with implicit C1 in _CST
The ASUS M6Ne specifies C2, implying C1
but not explicitly specifying it.
http://bugzilla.kernel.org/show_bug.cgi?id=4485
Signed-off-by: Janosch Machowinski <jmachowinski@gmx.de>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/acpi/processor_idle.c | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 83fd1b6c10c4..40c9f9ca5965 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -532,18 +532,10 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
| 532 | if (!pr->pblk) | 532 | if (!pr->pblk) |
| 533 | return_VALUE(-ENODEV); | 533 | return_VALUE(-ENODEV); |
| 534 | 534 | ||
| 535 | memset(pr->power.states, 0, sizeof(pr->power.states)); | ||
| 536 | |||
| 537 | /* if info is obtained from pblk/fadt, type equals state */ | 535 | /* if info is obtained from pblk/fadt, type equals state */ |
| 538 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | ||
| 539 | pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; | 536 | pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; |
| 540 | pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; | 537 | pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; |
| 541 | 538 | ||
| 542 | /* the C0 state only exists as a filler in our array, | ||
| 543 | * and all processors need to support C1 */ | ||
| 544 | pr->power.states[ACPI_STATE_C0].valid = 1; | ||
| 545 | pr->power.states[ACPI_STATE_C1].valid = 1; | ||
| 546 | |||
| 547 | #ifndef CONFIG_HOTPLUG_CPU | 539 | #ifndef CONFIG_HOTPLUG_CPU |
| 548 | /* | 540 | /* |
| 549 | * Check for P_LVL2_UP flag before entering C2 and above on | 541 | * Check for P_LVL2_UP flag before entering C2 and above on |
| @@ -573,12 +565,11 @@ static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) | |||
| 573 | { | 565 | { |
| 574 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); | 566 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); |
| 575 | 567 | ||
| 568 | /* Zero initialize all the C-states info. */ | ||
| 576 | memset(pr->power.states, 0, sizeof(pr->power.states)); | 569 | memset(pr->power.states, 0, sizeof(pr->power.states)); |
| 577 | 570 | ||
| 578 | /* if info is obtained from pblk/fadt, type equals state */ | 571 | /* set the first C-State to C1 */ |
| 579 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 572 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; |
| 580 | pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; | ||
| 581 | pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; | ||
| 582 | 573 | ||
| 583 | /* the C0 state only exists as a filler in our array, | 574 | /* the C0 state only exists as a filler in our array, |
| 584 | * and all processors need to support C1 */ | 575 | * and all processors need to support C1 */ |
| @@ -592,6 +583,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
| 592 | { | 583 | { |
| 593 | acpi_status status = 0; | 584 | acpi_status status = 0; |
| 594 | acpi_integer count; | 585 | acpi_integer count; |
| 586 | int current_count; | ||
| 595 | int i; | 587 | int i; |
| 596 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 588 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 597 | union acpi_object *cst; | 589 | union acpi_object *cst; |
| @@ -601,10 +593,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
| 601 | if (nocst) | 593 | if (nocst) |
| 602 | return_VALUE(-ENODEV); | 594 | return_VALUE(-ENODEV); |
| 603 | 595 | ||
| 604 | pr->power.count = 0; | 596 | current_count = 1; |
| 605 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) | 597 | |
| 606 | memset(&(pr->power.states[i]), 0, | 598 | /* Zero initialize C2 onwards and prepare for fresh CST lookup */ |
| 607 | sizeof(struct acpi_processor_cx)); | 599 | for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++) |
| 600 | memset(&(pr->power.states[i]), 0, | ||
| 601 | sizeof(struct acpi_processor_cx)); | ||
| 608 | 602 | ||
| 609 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); | 603 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); |
| 610 | if (ACPI_FAILURE(status)) { | 604 | if (ACPI_FAILURE(status)) { |
| @@ -632,16 +626,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
| 632 | goto end; | 626 | goto end; |
| 633 | } | 627 | } |
| 634 | 628 | ||
| 635 | /* We support up to ACPI_PROCESSOR_MAX_POWER. */ | ||
| 636 | if (count > ACPI_PROCESSOR_MAX_POWER) { | ||
| 637 | printk(KERN_WARNING | ||
| 638 | "Limiting number of power states to max (%d)\n", | ||
| 639 | ACPI_PROCESSOR_MAX_POWER); | ||
| 640 | printk(KERN_WARNING | ||
| 641 | "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); | ||
| 642 | count = ACPI_PROCESSOR_MAX_POWER; | ||
| 643 | } | ||
| 644 | |||
| 645 | /* Tell driver that at least _CST is supported. */ | 629 | /* Tell driver that at least _CST is supported. */ |
| 646 | pr->flags.has_cst = 1; | 630 | pr->flags.has_cst = 1; |
| 647 | 631 | ||
| @@ -685,7 +669,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
| 685 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) | 669 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) |
| 686 | continue; | 670 | continue; |
| 687 | 671 | ||
| 688 | if ((cx.type < ACPI_STATE_C1) || (cx.type > ACPI_STATE_C3)) | 672 | if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) |
| 689 | continue; | 673 | continue; |
| 690 | 674 | ||
| 691 | obj = (union acpi_object *)&(element->package.elements[2]); | 675 | obj = (union acpi_object *)&(element->package.elements[2]); |
| @@ -700,15 +684,28 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
| 700 | 684 | ||
| 701 | cx.power = obj->integer.value; | 685 | cx.power = obj->integer.value; |
| 702 | 686 | ||
| 703 | (pr->power.count)++; | 687 | current_count++; |
| 704 | memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx)); | 688 | memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); |
| 689 | |||
| 690 | /* | ||
| 691 | * We support total ACPI_PROCESSOR_MAX_POWER - 1 | ||
| 692 | * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1) | ||
| 693 | */ | ||
| 694 | if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) { | ||
| 695 | printk(KERN_WARNING | ||
| 696 | "Limiting number of power states to max (%d)\n", | ||
| 697 | ACPI_PROCESSOR_MAX_POWER); | ||
| 698 | printk(KERN_WARNING | ||
| 699 | "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); | ||
| 700 | break; | ||
| 701 | } | ||
| 705 | } | 702 | } |
| 706 | 703 | ||
| 707 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", | 704 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", |
| 708 | pr->power.count)); | 705 | current_count)); |
| 709 | 706 | ||
| 710 | /* Validate number of power states discovered */ | 707 | /* Validate number of power states discovered */ |
| 711 | if (pr->power.count < 2) | 708 | if (current_count < 2) |
| 712 | status = -EFAULT; | 709 | status = -EFAULT; |
| 713 | 710 | ||
| 714 | end: | 711 | end: |
| @@ -859,12 +856,13 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
| 859 | /* NOTE: the idle thread may not be running while calling | 856 | /* NOTE: the idle thread may not be running while calling |
| 860 | * this function */ | 857 | * this function */ |
| 861 | 858 | ||
| 859 | /* Adding C1 state */ | ||
| 860 | acpi_processor_get_power_info_default_c1(pr); | ||
| 862 | result = acpi_processor_get_power_info_cst(pr); | 861 | result = acpi_processor_get_power_info_cst(pr); |
| 863 | if (result == -ENODEV) | 862 | if (result == -ENODEV) |
| 864 | result = acpi_processor_get_power_info_fadt(pr); | 863 | acpi_processor_get_power_info_fadt(pr); |
| 865 | 864 | ||
| 866 | if ((result) || (acpi_processor_power_verify(pr) < 2)) | 865 | pr->power.count = acpi_processor_power_verify(pr); |
| 867 | result = acpi_processor_get_power_info_default_c1(pr); | ||
| 868 | 866 | ||
| 869 | /* | 867 | /* |
| 870 | * Set Default Policy | 868 | * Set Default Policy |
