diff options
Diffstat (limited to 'arch/x86/kernel/cpu/cpufreq/powernow-k8.c')
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 5c28b37dea1..6428aa17b40 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -939,10 +939,25 @@ static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) | |||
939 | free_cpumask_var(data->acpi_data.shared_cpu_map); | 939 | free_cpumask_var(data->acpi_data.shared_cpu_map); |
940 | } | 940 | } |
941 | 941 | ||
942 | static int get_transition_latency(struct powernow_k8_data *data) | ||
943 | { | ||
944 | int max_latency = 0; | ||
945 | int i; | ||
946 | for (i = 0; i < data->acpi_data.state_count; i++) { | ||
947 | int cur_latency = data->acpi_data.states[i].transition_latency | ||
948 | + data->acpi_data.states[i].bus_master_latency; | ||
949 | if (cur_latency > max_latency) | ||
950 | max_latency = cur_latency; | ||
951 | } | ||
952 | /* value in usecs, needs to be in nanoseconds */ | ||
953 | return 1000 * max_latency; | ||
954 | } | ||
955 | |||
942 | #else | 956 | #else |
943 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } | 957 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } |
944 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } | 958 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } |
945 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } | 959 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } |
960 | static int get_transition_latency(struct powernow_k8_data *data) { return 0; } | ||
946 | #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ | 961 | #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ |
947 | 962 | ||
948 | /* Take a frequency, and issue the fid/vid transition command */ | 963 | /* Take a frequency, and issue the fid/vid transition command */ |
@@ -1142,8 +1157,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1142 | data->cpu = pol->cpu; | 1157 | data->cpu = pol->cpu; |
1143 | data->currpstate = HW_PSTATE_INVALID; | 1158 | data->currpstate = HW_PSTATE_INVALID; |
1144 | 1159 | ||
1145 | rc = powernow_k8_cpu_init_acpi(data); | 1160 | if (powernow_k8_cpu_init_acpi(data)) { |
1146 | if (rc) { | ||
1147 | /* | 1161 | /* |
1148 | * Use the PSB BIOS structure. This is only availabe on | 1162 | * Use the PSB BIOS structure. This is only availabe on |
1149 | * an UP version, and is deprecated by AMD. | 1163 | * an UP version, and is deprecated by AMD. |
@@ -1161,19 +1175,28 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1161 | "ACPI maintainers and complain to your BIOS " | 1175 | "ACPI maintainers and complain to your BIOS " |
1162 | "vendor.\n"); | 1176 | "vendor.\n"); |
1163 | #endif | 1177 | #endif |
1164 | goto err_out; | 1178 | kfree(data); |
1179 | return -ENODEV; | ||
1165 | } | 1180 | } |
1166 | if (pol->cpu != 0) { | 1181 | if (pol->cpu != 0) { |
1167 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " | 1182 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " |
1168 | "CPU other than CPU0. Complain to your BIOS " | 1183 | "CPU other than CPU0. Complain to your BIOS " |
1169 | "vendor.\n"); | 1184 | "vendor.\n"); |
1170 | goto err_out; | 1185 | kfree(data); |
1186 | return -ENODEV; | ||
1171 | } | 1187 | } |
1172 | rc = find_psb_table(data); | 1188 | rc = find_psb_table(data); |
1173 | if (rc) { | 1189 | if (rc) { |
1174 | goto err_out; | 1190 | kfree(data); |
1191 | return -ENODEV; | ||
1175 | } | 1192 | } |
1176 | } | 1193 | /* Take a crude guess here. |
1194 | * That guess was in microseconds, so multiply with 1000 */ | ||
1195 | pol->cpuinfo.transition_latency = ( | ||
1196 | ((data->rvo + 8) * data->vstable * VST_UNITS_20US) + | ||
1197 | ((1 << data->irt) * 30)) * 1000; | ||
1198 | } else /* ACPI _PSS objects available */ | ||
1199 | pol->cpuinfo.transition_latency = get_transition_latency(data); | ||
1177 | 1200 | ||
1178 | /* only run on specific CPU from here on */ | 1201 | /* only run on specific CPU from here on */ |
1179 | oldmask = current->cpus_allowed; | 1202 | oldmask = current->cpus_allowed; |
@@ -1204,11 +1227,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1204 | cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu)); | 1227 | cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu)); |
1205 | data->available_cores = pol->cpus; | 1228 | data->available_cores = pol->cpus; |
1206 | 1229 | ||
1207 | /* Take a crude guess here. | ||
1208 | * That guess was in microseconds, so multiply with 1000 */ | ||
1209 | pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) | ||
1210 | + (3 * (1 << data->irt) * 10)) * 1000; | ||
1211 | |||
1212 | if (cpu_family == CPU_HW_PSTATE) | 1230 | if (cpu_family == CPU_HW_PSTATE) |
1213 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); | 1231 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); |
1214 | else | 1232 | else |