diff options
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 133 |
1 files changed, 82 insertions, 51 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index cc049338e418..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 | ||
97 | static struct dmi_system_id __initdata processor_power_dmi_table[] = { | 97 | static 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: |
@@ -892,12 +924,13 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
892 | /* NOTE: the idle thread may not be running while calling | 924 | /* NOTE: the idle thread may not be running while calling |
893 | * this function */ | 925 | * this function */ |
894 | 926 | ||
927 | /* Adding C1 state */ | ||
928 | acpi_processor_get_power_info_default_c1(pr); | ||
895 | result = acpi_processor_get_power_info_cst(pr); | 929 | result = acpi_processor_get_power_info_cst(pr); |
896 | if (result == -ENODEV) | 930 | if (result == -ENODEV) |
897 | result = acpi_processor_get_power_info_fadt(pr); | 931 | acpi_processor_get_power_info_fadt(pr); |
898 | 932 | ||
899 | if ((result) || (acpi_processor_power_verify(pr) < 2)) | 933 | pr->power.count = acpi_processor_power_verify(pr); |
900 | result = acpi_processor_get_power_info_default_c1(pr); | ||
901 | 934 | ||
902 | /* | 935 | /* |
903 | * Set Default Policy | 936 | * Set Default Policy |
@@ -1066,8 +1099,6 @@ int acpi_processor_power_init(struct acpi_processor *pr, | |||
1066 | } | 1099 | } |
1067 | } | 1100 | } |
1068 | 1101 | ||
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); | 1102 | acpi_processor_get_power_info(pr); |
1072 | 1103 | ||
1073 | /* | 1104 | /* |