diff options
Diffstat (limited to 'drivers/acpi')
-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 |