aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c148
1 files changed, 97 insertions, 51 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 807b0df308f1..be2dae52f6fa 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -95,22 +95,57 @@ static int set_max_cstate(struct dmi_system_id *id)
95} 95}
96 96
97static struct dmi_system_id __initdata processor_power_dmi_table[] = { 97static struct dmi_system_id __initdata processor_power_dmi_table[] = {
98 {set_max_cstate, "IBM ThinkPad R40e", { 98 { set_max_cstate, "IBM ThinkPad R40e", {
99 DMI_MATCH(DMI_BIOS_VENDOR, 99 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
100 "IBM"), 100 DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
101 DMI_MATCH(DMI_BIOS_VERSION, 101 { set_max_cstate, "IBM ThinkPad R40e", {
102 "1SET60WW")}, 102 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
103 (void *)1}, 103 DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
104 {set_max_cstate, "Medion 41700", { 104 { set_max_cstate, "IBM ThinkPad R40e", {
105 DMI_MATCH(DMI_BIOS_VENDOR, 105 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
106 "Phoenix Technologies LTD"), 106 DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
107 DMI_MATCH(DMI_BIOS_VERSION, 107 { set_max_cstate, "IBM ThinkPad R40e", {
108 "R01-A1J")}, (void *)1}, 108 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
109 {set_max_cstate, "Clevo 5600D", { 109 DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
110 DMI_MATCH(DMI_BIOS_VENDOR, 110 { set_max_cstate, "IBM ThinkPad R40e", {
111 "Phoenix Technologies LTD"), 111 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
112 DMI_MATCH(DMI_BIOS_VERSION, 112 DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
113 "SHE845M0.86C.0013.D.0302131307")}, 113 { set_max_cstate, "IBM ThinkPad R40e", {
114 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
115 DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
116 { set_max_cstate, "IBM ThinkPad R40e", {
117 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
118 DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
119 { set_max_cstate, "IBM ThinkPad R40e", {
120 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
121 DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
122 { set_max_cstate, "IBM ThinkPad R40e", {
123 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
124 DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
125 { set_max_cstate, "IBM ThinkPad R40e", {
126 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
127 DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
128 { set_max_cstate, "IBM ThinkPad R40e", {
129 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
130 DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
131 { set_max_cstate, "IBM ThinkPad R40e", {
132 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
133 DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
134 { set_max_cstate, "IBM ThinkPad R40e", {
135 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
136 DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
137 { set_max_cstate, "IBM ThinkPad R40e", {
138 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
139 DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
140 { set_max_cstate, "IBM ThinkPad R40e", {
141 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
142 DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
143 { set_max_cstate, "Medion 41700", {
144 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
145 DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
146 { set_max_cstate, "Clevo 5600D", {
147 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
148 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
114 (void *)2}, 149 (void *)2},
115 {}, 150 {},
116}; 151};
@@ -550,18 +585,10 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
550 if (!pr->pblk) 585 if (!pr->pblk)
551 return_VALUE(-ENODEV); 586 return_VALUE(-ENODEV);
552 587
553 memset(pr->power.states, 0, sizeof(pr->power.states));
554
555 /* if info is obtained from pblk/fadt, type equals state */ 588 /* 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; 589 pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
558 pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; 590 pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
559 591
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 592#ifndef CONFIG_HOTPLUG_CPU
566 /* 593 /*
567 * Check for P_LVL2_UP flag before entering C2 and above on 594 * Check for P_LVL2_UP flag before entering C2 and above on
@@ -591,12 +618,11 @@ static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
591{ 618{
592 ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); 619 ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
593 620
621 /* Zero initialize all the C-states info. */
594 memset(pr->power.states, 0, sizeof(pr->power.states)); 622 memset(pr->power.states, 0, sizeof(pr->power.states));
595 623
596 /* if info is obtained from pblk/fadt, type equals state */ 624 /* set the first C-State to C1 */
597 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; 625 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 626
601 /* the C0 state only exists as a filler in our array, 627 /* the C0 state only exists as a filler in our array,
602 * and all processors need to support C1 */ 628 * and all processors need to support C1 */
@@ -610,6 +636,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
610{ 636{
611 acpi_status status = 0; 637 acpi_status status = 0;
612 acpi_integer count; 638 acpi_integer count;
639 int current_count;
613 int i; 640 int i;
614 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 641 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
615 union acpi_object *cst; 642 union acpi_object *cst;
@@ -619,10 +646,12 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
619 if (nocst) 646 if (nocst)
620 return_VALUE(-ENODEV); 647 return_VALUE(-ENODEV);
621 648
622 pr->power.count = 0; 649 current_count = 1;
623 for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) 650
624 memset(&(pr->power.states[i]), 0, 651 /* Zero initialize C2 onwards and prepare for fresh CST lookup */
625 sizeof(struct acpi_processor_cx)); 652 for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
653 memset(&(pr->power.states[i]), 0,
654 sizeof(struct acpi_processor_cx));
626 655
627 status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); 656 status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
628 if (ACPI_FAILURE(status)) { 657 if (ACPI_FAILURE(status)) {
@@ -650,16 +679,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
650 goto end; 679 goto end;
651 } 680 }
652 681
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. */ 682 /* Tell driver that at least _CST is supported. */
664 pr->flags.has_cst = 1; 683 pr->flags.has_cst = 1;
665 684
@@ -703,7 +722,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
703 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) 722 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
704 continue; 723 continue;
705 724
706 if ((cx.type < ACPI_STATE_C1) || (cx.type > ACPI_STATE_C3)) 725 if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
707 continue; 726 continue;
708 727
709 obj = (union acpi_object *)&(element->package.elements[2]); 728 obj = (union acpi_object *)&(element->package.elements[2]);
@@ -718,15 +737,28 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
718 737
719 cx.power = obj->integer.value; 738 cx.power = obj->integer.value;
720 739
721 (pr->power.count)++; 740 current_count++;
722 memcpy(&(pr->power.states[pr->power.count]), &cx, sizeof(cx)); 741 memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx));
742
743 /*
744 * We support total ACPI_PROCESSOR_MAX_POWER - 1
745 * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1)
746 */
747 if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) {
748 printk(KERN_WARNING
749 "Limiting number of power states to max (%d)\n",
750 ACPI_PROCESSOR_MAX_POWER);
751 printk(KERN_WARNING
752 "Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");
753 break;
754 }
723 } 755 }
724 756
725 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", 757 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n",
726 pr->power.count)); 758 current_count));
727 759
728 /* Validate number of power states discovered */ 760 /* Validate number of power states discovered */
729 if (pr->power.count < 2) 761 if (current_count < 2)
730 status = -EFAULT; 762 status = -EFAULT;
731 763
732 end: 764 end:
@@ -843,6 +875,15 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
843 unsigned int i; 875 unsigned int i;
844 unsigned int working = 0; 876 unsigned int working = 0;
845 877
878#ifdef ARCH_APICTIMER_STOPS_ON_C3
879 struct cpuinfo_x86 *c = cpu_data + pr->id;
880 cpumask_t mask = cpumask_of_cpu(pr->id);
881
882 if (c->x86_vendor == X86_VENDOR_INTEL) {
883 on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
884 }
885#endif
886
846 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { 887 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
847 struct acpi_processor_cx *cx = &pr->power.states[i]; 888 struct acpi_processor_cx *cx = &pr->power.states[i];
848 889
@@ -857,6 +898,12 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
857 898
858 case ACPI_STATE_C3: 899 case ACPI_STATE_C3:
859 acpi_processor_power_verify_c3(pr, cx); 900 acpi_processor_power_verify_c3(pr, cx);
901#ifdef ARCH_APICTIMER_STOPS_ON_C3
902 if (c->x86_vendor == X86_VENDOR_INTEL) {
903 on_each_cpu(switch_APIC_timer_to_ipi,
904 &mask, 1, 1);
905 }
906#endif
860 break; 907 break;
861 } 908 }
862 909
@@ -877,12 +924,13 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
877 /* NOTE: the idle thread may not be running while calling 924 /* NOTE: the idle thread may not be running while calling
878 * this function */ 925 * this function */
879 926
927 /* Adding C1 state */
928 acpi_processor_get_power_info_default_c1(pr);
880 result = acpi_processor_get_power_info_cst(pr); 929 result = acpi_processor_get_power_info_cst(pr);
881 if (result == -ENODEV) 930 if (result == -ENODEV)
882 result = acpi_processor_get_power_info_fadt(pr); 931 acpi_processor_get_power_info_fadt(pr);
883 932
884 if ((result) || (acpi_processor_power_verify(pr) < 2)) 933 pr->power.count = acpi_processor_power_verify(pr);
885 result = acpi_processor_get_power_info_default_c1(pr);
886 934
887 /* 935 /*
888 * Set Default Policy 936 * Set Default Policy
@@ -1051,8 +1099,6 @@ int acpi_processor_power_init(struct acpi_processor *pr,
1051 } 1099 }
1052 } 1100 }
1053 1101
1054 acpi_processor_power_init_pdc(&(pr->power), pr->id);
1055 acpi_processor_set_pdc(pr, pr->power.pdc);
1056 acpi_processor_get_power_info(pr); 1102 acpi_processor_get_power_info(pr);
1057 1103
1058 /* 1104 /*