[CPUFREQ] powernow-k8: Get transition latency from ACPI _PSS table
[pandora-kernel.git] / arch / x86 / kernel / cpu / cpufreq / powernow-k8.c
index c3c9adb..fb039cd 100644 (file)
@@ -939,10 +939,25 @@ static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
        free_cpumask_var(data->acpi_data.shared_cpu_map);
 }
 
+static int get_transition_latency(struct powernow_k8_data *data)
+{
+       int max_latency = 0;
+       int i;
+       for (i = 0; i < data->acpi_data.state_count; i++) {
+               int cur_latency = data->acpi_data.states[i].transition_latency
+                       + data->acpi_data.states[i].bus_master_latency;
+               if (cur_latency > max_latency)
+                       max_latency = cur_latency;
+       }
+       /* value in usecs, needs to be in nanoseconds */
+       return 1000 * max_latency;
+}
+
 #else
 static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
 static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
+static int get_transition_latency(struct powernow_k8_data *data) { return 0; }
 #endif /* CONFIG_X86_POWERNOW_K8_ACPI */
 
 /* Take a frequency, and issue the fid/vid transition command */
@@ -1173,7 +1188,13 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
                if (rc) {
                        goto err_out;
                }
-       }
+               /* Take a crude guess here.
+                * That guess was in microseconds, so multiply with 1000 */
+               pol->cpuinfo.transition_latency = (
+                        ((data->rvo + 8) * data->vstable * VST_UNITS_20US) +
+                        ((1 << data->irt) * 30)) * 1000;
+       } else /* ACPI _PSS objects available */
+               pol->cpuinfo.transition_latency = get_transition_latency(data);
 
        /* only run on specific CPU from here on */
        oldmask = current->cpus_allowed;
@@ -1199,15 +1220,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
        set_cpus_allowed_ptr(current, &oldmask);
 
        if (cpu_family == CPU_HW_PSTATE)
-               pol->cpus = cpumask_of_cpu(pol->cpu);
+               cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
        else
-               pol->cpus = per_cpu(cpu_core_map, pol->cpu);
-       data->available_cores = &(pol->cpus);
-
-       /* Take a crude guess here.
-        * That guess was in microseconds, so multiply with 1000 */
-       pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US)
-           + (3 * (1 << data->irt) * 10)) * 1000;
+               cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu));
+       data->available_cores = pol->cpus;
 
        if (cpu_family == CPU_HW_PSTATE)
                pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);