diff options
-rw-r--r-- | xen/arch/x86/acpi/cpufreq/cpufreq.c | 8 | ||||
-rw-r--r-- | xen/arch/x86/acpi/cpufreq/powernow.c | 64 | ||||
-rw-r--r-- | xen/include/acpi/cpufreq/processor_perf.h | 1 |
3 files changed, 28 insertions, 45 deletions
diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c index 8408f1669e..643fad7550 100644 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c @@ -661,6 +661,9 @@ static int __init cpufreq_driver_init(void) if ((cpufreq_controller == FREQCTL_xen) && (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ret = cpufreq_register_driver(&acpi_cpufreq_driver); + else if ((cpufreq_controller == FREQCTL_xen) && + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) + ret = powernow_register_driver(); return ret; } @@ -676,9 +679,8 @@ int cpufreq_cpu_init(unsigned int cpuid) /* Currently we only handle Intel and AMD processor */ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) ret = cpufreq_add_cpu(cpuid); - else if ( (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && - (cpu_count == num_online_cpus()) ) - ret = powernow_cpufreq_init(); + else if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) + ret = cpufreq_add_cpu(cpuid); else ret = -EFAULT; return ret; diff --git a/xen/arch/x86/acpi/cpufreq/powernow.c b/xen/arch/x86/acpi/cpufreq/powernow.c index 610a28e3ea..32af03119f 100644 --- a/xen/arch/x86/acpi/cpufreq/powernow.c +++ b/xen/arch/x86/acpi/cpufreq/powernow.c @@ -85,6 +85,7 @@ static int powernow_cpufreq_target(struct cpufreq_policy *policy, unsigned int next_state = 0; /* Index into freq_table */ unsigned int next_perf_state = 0; /* Index into perf table */ int result = 0; + int j = 0; if (unlikely(data == NULL || data->acpi_data == NULL || data->freq_table == NULL)) { @@ -123,6 +124,9 @@ static int powernow_cpufreq_target(struct cpufreq_policy *policy, on_selected_cpus(&cmd.mask, transition_pstate, &cmd, 0); + for_each_cpu_mask(j, online_policy_cpus) + cpufreq_statistic_update(j, perf->state, next_perf_state); + perf->state = next_perf_state; policy->cur = freqs.new; @@ -132,10 +136,17 @@ static int powernow_cpufreq_target(struct cpufreq_policy *policy, static int powernow_cpufreq_verify(struct cpufreq_policy *policy) { struct powernow_cpufreq_data *data; + struct processor_performance *perf; - if (!policy || !(data = drv_data[policy->cpu])) + if (!policy || !(data = drv_data[policy->cpu]) || + !processor_pminfo[policy->cpu]) return -EINVAL; + perf = &processor_pminfo[policy->cpu]->perf; + + cpufreq_verify_within_limits(policy, 0, + perf->states[perf->platform_limit].core_frequency * 1000); + return cpufreq_frequency_table_verify(policy, data->freq_table); } @@ -202,6 +213,8 @@ static int powernow_cpufreq_cpu_init(struct cpufreq_policy *policy) perf->states[i].transition_latency * 1000; } + policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR; + data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ for (i = 0; i < perf->state_count && i <= max_hw_pstate; i++) { @@ -259,10 +272,17 @@ static struct cpufreq_driver powernow_cpufreq_driver = { .exit = powernow_cpufreq_cpu_exit }; +unsigned int powernow_register_driver() +{ + unsigned int ret; + ret = cpufreq_register_driver(&powernow_cpufreq_driver); + return ret; +} + int powernow_cpufreq_init(void) { unsigned int i, ret = 0; - unsigned int dom, max_dom = 0; + unsigned int max_dom = 0; cpumask_t *pt; unsigned long *dom_mask; @@ -304,46 +324,6 @@ int powernow_cpufreq_init(void) processor_pminfo[i]->perf.shared_cpu_map = pt[processor_pminfo[i]->perf.domain_info.domain]; - cpufreq_driver = &powernow_cpufreq_driver; - - /* setup cpufreq infrastructure */ - for_each_online_cpu(i) { - struct cpufreq_policy *policy = cpufreq_cpu_policy[i]; - - if (!policy) { - unsigned int firstcpu; - - firstcpu = first_cpu(processor_pminfo[i]->perf.shared_cpu_map); - if (i == firstcpu) { - policy = xmalloc(struct cpufreq_policy); - if (!policy) { - ret = -ENOMEM; - goto cpufreq_init_out; - } - memset(policy, 0, sizeof(struct cpufreq_policy)); - policy->cpu = i; - } else - policy = cpufreq_cpu_policy[firstcpu]; - cpu_set(i, policy->cpus); - cpufreq_cpu_policy[i] = policy; - } - - ret = powernow_cpufreq_cpu_init(policy); - if (ret) - goto cpufreq_init_out; - } - - /* setup ondemand cpufreq */ - for (dom = 0; dom < max_dom; dom++) { - if (!test_bit(dom, dom_mask)) - continue; - i = first_cpu(pt[dom]); - ret = cpufreq_governor_dbs(cpufreq_cpu_policy[i], CPUFREQ_GOV_START); - if (ret) - goto cpufreq_init_out; - } - -cpufreq_init_out: xfree(pt); xfree(dom_mask); diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h index cc6be7a913..72b55ead82 100644 --- a/xen/include/acpi/cpufreq/processor_perf.h +++ b/xen/include/acpi/cpufreq/processor_perf.h @@ -8,6 +8,7 @@ int get_cpu_id(u8); int powernow_cpufreq_init(void); +unsigned int powernow_register_driver(void); void cpufreq_residency_update(unsigned int, uint8_t); void cpufreq_statistic_update(unsigned int, uint8_t, uint8_t); |