return 0;
policy = cpufreq_cpu_policy[cpu];
- if (!policy)
+ if (!policy || !policy->aperf_mperf)
return 0;
switch (flag)
return freq;
}
+static void feature_detect(void *info)
+{
+ struct cpufreq_policy *policy = info;
+ unsigned int eax, ecx;
+
+ ecx = cpuid_ecx(6);
+ if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) {
+ policy->aperf_mperf = 1;
+ acpi_cpufreq_driver.getavg = get_measured_perf;
+ }
+
+ eax = cpuid_eax(6);
+ if (eax & 0x2) {
+ policy->turbo = CPUFREQ_TURBO_ENABLED;
+ if (cpufreq_verbose)
+ printk(XENLOG_INFO "CPU%u: Turbo Mode detected and enabled\n",
+ smp_processor_id());
+ }
+}
+
static unsigned int check_freqs(cpumask_t mask, unsigned int freq,
struct acpi_cpufreq_data *data)
{
/* Check for APERF/MPERF support in hardware
* also check for boost support */
- if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) {
- unsigned int ecx;
- unsigned int eax;
- ecx = cpuid_ecx(6);
- if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
- acpi_cpufreq_driver.getavg = get_measured_perf;
- eax = cpuid_eax(6);
- if ( eax & 0x2 ) {
- policy->turbo = CPUFREQ_TURBO_ENABLED;
- printk(XENLOG_INFO "Turbo Mode detected and enabled!\n");
- }
- }
+ if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6)
+ on_selected_cpus(cpumask_of(cpu), feature_detect, policy, 1);
/*
* the first call to ->target() should result in us actually
return cpufreq_frequency_table_verify(policy, data->freq_table);
}
+static void feature_detect(void *info)
+{
+ struct cpufreq_policy *policy = info;
+ unsigned int ecx, edx;
+
+ ecx = cpuid_ecx(6);
+ if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY) {
+ policy->aperf_mperf = 1;
+ powernow_cpufreq_driver.getavg = get_measured_perf;
+ }
+
+ edx = cpuid_edx(CPUID_FREQ_VOLT_CAPABILITIES);
+ if ((edx & CPB_CAPABLE) == CPB_CAPABLE) {
+ policy->turbo = CPUFREQ_TURBO_ENABLED;
+ if (cpufreq_verbose)
+ printk(XENLOG_INFO
+ "CPU%u: Core Boost/Turbo detected and enabled\n",
+ smp_processor_id());
+ }
+}
+
static int powernow_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
unsigned int i;
if (result)
goto err_freqfree;
- if (c->cpuid_level >= 6) {
- unsigned int edx;
- unsigned int ecx;
- ecx = cpuid_ecx(6);
- if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
- powernow_cpufreq_driver.getavg = get_measured_perf;
- edx = cpuid_edx(CPUID_FREQ_VOLT_CAPABILITIES);
- if ((edx & CPB_CAPABLE) == CPB_CAPABLE) {
- policy->turbo = CPUFREQ_TURBO_ENABLED;
- printk(XENLOG_INFO "Core Boost/Turbo detected and enabled\n");
- }
- }
+ if (c->cpuid_level >= 6)
+ on_selected_cpus(cpumask_of(cpu), feature_detect, policy, 1);
/*
* the first call to ->target() should result in us actually
* governors are used */
struct cpufreq_governor *governor;
- unsigned int resume; /* flag for cpufreq 1st run
+ bool_t resume; /* flag for cpufreq 1st run
* S3 wakeup, hotplug cpu, etc */
- int turbo; /* tristate flag: 0 for unsupported
+ s8 turbo; /* tristate flag: 0 for unsupported
* -1 for disable, 1 for enabled
* See CPUFREQ_TURBO_* below for defines */
+ bool_t aperf_mperf; /* CPU has APERF/MPERF MSRs */
};
extern struct cpufreq_policy *cpufreq_cpu_policy[NR_CPUS];