diff options
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 139 |
1 files changed, 86 insertions, 53 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index cc049338e418..eb730a80952c 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -94,23 +94,60 @@ static int set_max_cstate(struct dmi_system_id *id) | |||
94 | return 0; | 94 | return 0; |
95 | } | 95 | } |
96 | 96 | ||
97 | static struct dmi_system_id __initdata processor_power_dmi_table[] = { | 97 | /* Actually this shouldn't be __cpuinitdata, would be better to fix the |
98 | {set_max_cstate, "IBM ThinkPad R40e", { | 98 | callers to only run once -AK */ |
99 | DMI_MATCH(DMI_BIOS_VENDOR, | 99 | static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { |
100 | "IBM"), | 100 | { set_max_cstate, "IBM ThinkPad R40e", { |
101 | DMI_MATCH(DMI_BIOS_VERSION, | 101 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
102 | "1SET60WW")}, | 102 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, |
103 | (void *)1}, | 103 | { set_max_cstate, "IBM ThinkPad R40e", { |
104 | {set_max_cstate, "Medion 41700", { | 104 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
105 | DMI_MATCH(DMI_BIOS_VENDOR, | 105 | DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1}, |
106 | "Phoenix Technologies LTD"), | 106 | { set_max_cstate, "IBM ThinkPad R40e", { |
107 | DMI_MATCH(DMI_BIOS_VERSION, | 107 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
108 | "R01-A1J")}, (void *)1}, | 108 | DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1}, |
109 | {set_max_cstate, "Clevo 5600D", { | 109 | { set_max_cstate, "IBM ThinkPad R40e", { |
110 | DMI_MATCH(DMI_BIOS_VENDOR, | 110 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
111 | "Phoenix Technologies LTD"), | 111 | DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1}, |
112 | DMI_MATCH(DMI_BIOS_VERSION, | 112 | { set_max_cstate, "IBM ThinkPad R40e", { |
113 | "SHE845M0.86C.0013.D.0302131307")}, | 113 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
114 | DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1}, | ||
115 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
116 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
117 | DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1}, | ||
118 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
119 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
120 | DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1}, | ||
121 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
122 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
123 | DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1}, | ||
124 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
125 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
126 | DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1}, | ||
127 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
128 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
129 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, | ||
130 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
131 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
132 | DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1}, | ||
133 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
134 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
135 | DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1}, | ||
136 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
137 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
138 | DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1}, | ||
139 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
140 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
141 | DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1}, | ||
142 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
143 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
144 | DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1}, | ||
145 | { set_max_cstate, "Medion 41700", { | ||
146 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | ||
147 | DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1}, | ||
148 | { set_max_cstate, "Clevo 5600D", { | ||
149 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | ||
150 | DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, | ||
114 | (void *)2}, | 151 | (void *)2}, |
115 | {}, | 152 | {}, |
116 | }; | 153 | }; |
@@ -550,18 +587,10 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
550 | if (!pr->pblk) | 587 | if (!pr->pblk) |
551 | return_VALUE(-ENODEV); | 588 | return_VALUE(-ENODEV); |
552 | 589 | ||
553 | memset(pr->power.states, 0, sizeof(pr->power.states)); | ||
554 | |||
555 | /* if info is obtained from pblk/fadt, type equals state */ | 590 | /* if info is obtained from pblk/fadt, type equals state */ |
556 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | ||
557 | pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; | 591 | pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; |
558 | pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; | 592 | pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; |
559 | 593 | ||
560 | /* the C0 state only exists as a filler in our array, | ||
561 | * and all processors need to support C1 */ | ||
562 | pr->power.states[ACPI_STATE_C0].valid = 1; | ||
563 | pr->power.states[ACPI_STATE_C1].valid = 1; | ||
564 | |||
565 | #ifndef CONFIG_HOTPLUG_CPU | 594 | #ifndef CONFIG_HOTPLUG_CPU |
566 | /* | 595 | /* |
567 | * Check for P_LVL2_UP flag before entering C2 and above on | 596 | * Check for P_LVL2_UP flag before entering C2 and above on |
@@ -591,12 +620,11 @@ static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) | |||
591 | { | 620 | { |
592 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); | 621 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); |
593 | 622 | ||
623 | /* Zero initialize all the C-states info. */ | ||
594 | memset(pr->power.states, 0, sizeof(pr->power.states)); | 624 | memset(pr->power.states, 0, sizeof(pr->power.states)); |
595 | 625 | ||
596 | /* if info is obtained from pblk/fadt, type equals state */ | 626 | /* set the first C-State to C1 */ |
597 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 627 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; |
598 | pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; | ||
599 | pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; | ||
600 | 628 | ||
601 | /* the C0 state only exists as a filler in our array, | 629 | /* the C0 state only exists as a filler in our array, |
602 | * and all processors need to support C1 */ | 630 | * and all processors need to support C1 */ |
@@ -610,6 +638,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
610 | { | 638 | { |
611 | acpi_status status = 0; | 639 | acpi_status status = 0; |
612 | acpi_integer count; | 640 | acpi_integer count; |
641 | int current_count; | ||
613 | int i; | 642 | int i; |
614 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 643 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
615 | union acpi_object *cst; | 644 | union acpi_object *cst; |
@@ -619,10 +648,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
619 | if (nocst) | 648 | if (nocst) |
620 | return_VALUE(-ENODEV); | 649 | return_VALUE(-ENODEV); |
621 | 650 | ||
622 | pr->power.count = 0; | 651 | current_count = 1; |
623 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) | 652 | |
624 | memset(&(pr->power.states[i]), 0, | 653 | /* Zero initialize C2 onwards and prepare for fresh CST lookup */ |
625 | sizeof(struct acpi_processor_cx)); | 654 | for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++) |
655 | memset(&(pr->power.states[i]), 0, | ||
656 | sizeof(struct acpi_processor_cx)); | ||
626 | 657 | ||
627 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); | 658 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); |
628 | if (ACPI_FAILURE(status)) { | 659 | if (ACPI_FAILURE(status)) { |
@@ -650,16 +681,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
650 | goto end; | 681 | goto end; |
651 | } | 682 | } |
652 | 683 | ||
653 | /* We support up to ACPI_PROCESSOR_MAX_POWER. */ | ||
654 | if (count > ACPI_PROCESSOR_MAX_POWER) { | ||
655 | printk(KERN_WARNING | ||
656 | "Limiting number of power states to max (%d)\n", | ||
657 | ACPI_PROCESSOR_MAX_POWER); | ||
658 | printk(KERN_WARNING | ||
659 | "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); | ||
660 | count = ACPI_PROCESSOR_MAX_POWER; | ||
661 | } | ||
662 | |||
663 | /* Tell driver that at least _CST is supported. */ | 684 | /* Tell driver that at least _CST is supported. */ |
664 | pr->flags.has_cst = 1; | 685 | pr->flags.has_cst = 1; |
665 | 686 | ||
@@ -703,7 +724,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
703 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) | 724 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) |
704 | continue; | 725 | continue; |
705 | 726 | ||
706 | if ((cx.type < ACPI_STATE_C1) || (cx.type > ACPI_STATE_C3)) | 727 | if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) |
707 | continue; | 728 | continue; |
708 | 729 | ||
709 | obj = (union acpi_object *)&(element->package.elements[2]); | 730 | obj = (union acpi_object *)&(element->package.elements[2]); |
@@ -718,15 +739,28 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
718 | 739 | ||
719 | cx.power = obj->integer.value; | 740 | cx.power = obj->integer.value; |
720 | 741 | ||
721 | (pr->power.count)++; | 742 | current_count++; |
722 | memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx)); | 743 | memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); |
744 | |||
745 | /* | ||
746 | * We support total ACPI_PROCESSOR_MAX_POWER - 1 | ||
747 | * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1) | ||
748 | */ | ||
749 | if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) { | ||
750 | printk(KERN_WARNING | ||
751 | "Limiting number of power states to max (%d)\n", | ||
752 | ACPI_PROCESSOR_MAX_POWER); | ||
753 | printk(KERN_WARNING | ||
754 | "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); | ||
755 | break; | ||
756 | } | ||
723 | } | 757 | } |
724 | 758 | ||
725 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", | 759 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", |
726 | pr->power.count)); | 760 | current_count)); |
727 | 761 | ||
728 | /* Validate number of power states discovered */ | 762 | /* Validate number of power states discovered */ |
729 | if (pr->power.count < 2) | 763 | if (current_count < 2) |
730 | status = -EFAULT; | 764 | status = -EFAULT; |
731 | 765 | ||
732 | end: | 766 | end: |
@@ -867,7 +901,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
867 | case ACPI_STATE_C3: | 901 | case ACPI_STATE_C3: |
868 | acpi_processor_power_verify_c3(pr, cx); | 902 | acpi_processor_power_verify_c3(pr, cx); |
869 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 | 903 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 |
870 | if (c->x86_vendor == X86_VENDOR_INTEL) { | 904 | if (cx->valid && c->x86_vendor == X86_VENDOR_INTEL) { |
871 | on_each_cpu(switch_APIC_timer_to_ipi, | 905 | on_each_cpu(switch_APIC_timer_to_ipi, |
872 | &mask, 1, 1); | 906 | &mask, 1, 1); |
873 | } | 907 | } |
@@ -892,12 +926,13 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
892 | /* NOTE: the idle thread may not be running while calling | 926 | /* NOTE: the idle thread may not be running while calling |
893 | * this function */ | 927 | * this function */ |
894 | 928 | ||
929 | /* Adding C1 state */ | ||
930 | acpi_processor_get_power_info_default_c1(pr); | ||
895 | result = acpi_processor_get_power_info_cst(pr); | 931 | result = acpi_processor_get_power_info_cst(pr); |
896 | if (result == -ENODEV) | 932 | if (result == -ENODEV) |
897 | result = acpi_processor_get_power_info_fadt(pr); | 933 | acpi_processor_get_power_info_fadt(pr); |
898 | 934 | ||
899 | if ((result) || (acpi_processor_power_verify(pr) < 2)) | 935 | pr->power.count = acpi_processor_power_verify(pr); |
900 | result = acpi_processor_get_power_info_default_c1(pr); | ||
901 | 936 | ||
902 | /* | 937 | /* |
903 | * Set Default Policy | 938 | * Set Default Policy |
@@ -1066,8 +1101,6 @@ int acpi_processor_power_init(struct acpi_processor *pr, | |||
1066 | } | 1101 | } |
1067 | } | 1102 | } |
1068 | 1103 | ||
1069 | acpi_processor_power_init_pdc(&(pr->power), pr->id); | ||
1070 | acpi_processor_set_pdc(pr, pr->power.pdc); | ||
1071 | acpi_processor_get_power_info(pr); | 1104 | acpi_processor_get_power_info(pr); |
1072 | 1105 | ||
1073 | /* | 1106 | /* |