aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Herrmann <andreas.herrmann3@amd.com>2012-01-06 09:57:55 -0500
committerDave Jones <davej@redhat.com>2012-01-06 10:10:53 -0500
commita8eb28480e9b637cc78b9aa5e08612ba97e1317a (patch)
treee6aeca464fb9f3769c8376c591b063f3c54d3938 /drivers
parent201bf0f129e1715a33568d1563d9a75b840ab4d3 (diff)
[CPUFREQ] powernow-k8: Fix indexing issue
The driver uses the pstate number from the status register as index in its table of ACPI pstates (powernow_table). This is wrong as this is not a 1-to-1 mapping. For example we can have _PSS information to just utilize Pstate 0 and Pstate 4, ie. powernow-k8: Core Performance Boosting: on. powernow-k8: 0 : pstate 0 (2200 MHz) powernow-k8: 1 : pstate 4 (1400 MHz) In this example the driver's powernow_table has just 2 entries. Using the pstate number (4) as index into this table is just plain wrong. Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/powernow-k8.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index e0329f9fa40e..ad683ec2c57e 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -54,6 +54,9 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
54 54
55static int cpu_family = CPU_OPTERON; 55static int cpu_family = CPU_OPTERON;
56 56
57/* array to map SW pstate number to acpi state */
58static u32 ps_to_as[8];
59
57/* core performance boost */ 60/* core performance boost */
58static bool cpb_capable, cpb_enabled; 61static bool cpb_capable, cpb_enabled;
59static struct msr __percpu *msrs; 62static struct msr __percpu *msrs;
@@ -80,9 +83,9 @@ static u32 find_khz_freq_from_fid(u32 fid)
80} 83}
81 84
82static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, 85static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
83 u32 pstate) 86 u32 pstate)
84{ 87{
85 return data[pstate].frequency; 88 return data[ps_to_as[pstate]].frequency;
86} 89}
87 90
88/* Return the vco fid for an input fid 91/* Return the vco fid for an input fid
@@ -926,6 +929,9 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
926 invalidate_entry(powernow_table, i); 929 invalidate_entry(powernow_table, i);
927 continue; 930 continue;
928 } 931 }
932
933 ps_to_as[index] = i;
934
929 /* Frequency may be rounded for these */ 935 /* Frequency may be rounded for these */
930 if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) 936 if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
931 || boot_cpu_data.x86 == 0x11) { 937 || boot_cpu_data.x86 == 0x11) {
@@ -1190,7 +1196,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
1190 powernow_k8_acpi_pst_values(data, newstate); 1196 powernow_k8_acpi_pst_values(data, newstate);
1191 1197
1192 if (cpu_family == CPU_HW_PSTATE) 1198 if (cpu_family == CPU_HW_PSTATE)
1193 ret = transition_frequency_pstate(data, newstate); 1199 ret = transition_frequency_pstate(data,
1200 data->powernow_table[newstate].index);
1194 else 1201 else
1195 ret = transition_frequency_fidvid(data, newstate); 1202 ret = transition_frequency_fidvid(data, newstate);
1196 if (ret) { 1203 if (ret) {
@@ -1203,7 +1210,7 @@ static int powernowk8_target(struct cpufreq_policy *pol,
1203 1210
1204 if (cpu_family == CPU_HW_PSTATE) 1211 if (cpu_family == CPU_HW_PSTATE)
1205 pol->cur = find_khz_freq_from_pstate(data->powernow_table, 1212 pol->cur = find_khz_freq_from_pstate(data->powernow_table,
1206 newstate); 1213 data->powernow_table[newstate].index);
1207 else 1214 else
1208 pol->cur = find_khz_freq_from_fid(data->currfid); 1215 pol->cur = find_khz_freq_from_fid(data->currfid);
1209 ret = 0; 1216 ret = 0;