提交 c71bd694 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq

* master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] Fix ondemand vs suspend deadlock
  [CPUFREQ] Fix powernow-k8 SMP kernel on UP hardware bug.
  [PATCH] redirect speedstep-centrino maintainer mail to cpufreq list
  [CPUFREQ] correct powernow-k8 fid/vid masks for extended parts
  [CPUFREQ] Clarify powernow-k8 cpu_family statements
...@@ -120,7 +120,7 @@ static int pending_bit_stuck(void) ...@@ -120,7 +120,7 @@ static int pending_bit_stuck(void)
{ {
u32 lo, hi; u32 lo, hi;
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
return 0; return 0;
rdmsr(MSR_FIDVID_STATUS, lo, hi); rdmsr(MSR_FIDVID_STATUS, lo, hi);
...@@ -136,7 +136,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) ...@@ -136,7 +136,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
u32 lo, hi; u32 lo, hi;
u32 i = 0; u32 i = 0;
if (cpu_family) { if (cpu_family == CPU_HW_PSTATE) {
rdmsr(MSR_PSTATE_STATUS, lo, hi); rdmsr(MSR_PSTATE_STATUS, lo, hi);
i = lo & HW_PSTATE_MASK; i = lo & HW_PSTATE_MASK;
rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi);
...@@ -598,7 +598,7 @@ static void print_basics(struct powernow_k8_data *data) ...@@ -598,7 +598,7 @@ static void print_basics(struct powernow_k8_data *data)
int j; int j;
for (j = 0; j < data->numps; j++) { for (j = 0; j < data->numps; j++) {
if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) {
if (cpu_family) { if (cpu_family == CPU_HW_PSTATE) {
printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8,
(data->powernow_table[j].index & 0xff0000) >> 16, (data->powernow_table[j].index & 0xff0000) >> 16,
data->powernow_table[j].frequency/1000); data->powernow_table[j].frequency/1000);
...@@ -758,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data) ...@@ -758,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data)
#ifdef CONFIG_X86_POWERNOW_K8_ACPI #ifdef CONFIG_X86_POWERNOW_K8_ACPI
static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
{ {
if (!data->acpi_data.state_count || cpu_family) if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
return; return;
data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
...@@ -801,7 +801,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) ...@@ -801,7 +801,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
goto err_out; goto err_out;
} }
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
ret_val = fill_powernow_table_pstate(data, powernow_table); ret_val = fill_powernow_table_pstate(data, powernow_table);
else else
ret_val = fill_powernow_table_fidvid(data, powernow_table); ret_val = fill_powernow_table_fidvid(data, powernow_table);
...@@ -885,8 +885,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf ...@@ -885,8 +885,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf
u32 vid; u32 vid;
if (data->exttype) { if (data->exttype) {
fid = data->acpi_data.states[i].status & FID_MASK; fid = data->acpi_data.states[i].status & EXT_FID_MASK;
vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK;
} else { } else {
fid = data->acpi_data.states[i].control & FID_MASK; fid = data->acpi_data.states[i].control & FID_MASK;
vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
...@@ -1082,7 +1082,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi ...@@ -1082,7 +1082,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
if (query_current_values_with_pending_wait(data)) if (query_current_values_with_pending_wait(data))
goto err_out; goto err_out;
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
dprintk("targ: curr fid 0x%x, did 0x%x\n", dprintk("targ: curr fid 0x%x, did 0x%x\n",
data->currfid, data->currvid); data->currfid, data->currvid);
else { else {
...@@ -1103,7 +1103,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi ...@@ -1103,7 +1103,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
powernow_k8_acpi_pst_values(data, newstate); powernow_k8_acpi_pst_values(data, newstate);
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
ret = transition_frequency_pstate(data, newstate); ret = transition_frequency_pstate(data, newstate);
else else
ret = transition_frequency_fidvid(data, newstate); ret = transition_frequency_fidvid(data, newstate);
...@@ -1115,7 +1115,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi ...@@ -1115,7 +1115,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
} }
mutex_unlock(&fidvid_mutex); mutex_unlock(&fidvid_mutex);
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
else else
pol->cur = find_khz_freq_from_fid(data->currfid); pol->cur = find_khz_freq_from_fid(data->currfid);
...@@ -1163,7 +1163,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) ...@@ -1163,7 +1163,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
* Use the PSB BIOS structure. This is only availabe on * Use the PSB BIOS structure. This is only availabe on
* an UP version, and is deprecated by AMD. * an UP version, and is deprecated by AMD.
*/ */
if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { if (num_online_cpus() != 1) {
printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
kfree(data); kfree(data);
return -ENODEV; return -ENODEV;
...@@ -1197,14 +1197,14 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) ...@@ -1197,14 +1197,14 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
if (query_current_values_with_pending_wait(data)) if (query_current_values_with_pending_wait(data))
goto err_out; goto err_out;
if (!cpu_family) if (cpu_family == CPU_OPTERON)
fidvid_msr_init(); fidvid_msr_init();
/* run on any CPU again */ /* run on any CPU again */
set_cpus_allowed(current, oldmask); set_cpus_allowed(current, oldmask);
pol->governor = CPUFREQ_DEFAULT_GOVERNOR; pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
pol->cpus = cpumask_of_cpu(pol->cpu); pol->cpus = cpumask_of_cpu(pol->cpu);
else else
pol->cpus = cpu_core_map[pol->cpu]; pol->cpus = cpu_core_map[pol->cpu];
...@@ -1215,7 +1215,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) ...@@ -1215,7 +1215,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US)
+ (3 * (1 << data->irt) * 10)) * 1000; + (3 * (1 << data->irt) * 10)) * 1000;
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
else else
pol->cur = find_khz_freq_from_fid(data->currfid); pol->cur = find_khz_freq_from_fid(data->currfid);
...@@ -1232,7 +1232,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) ...@@ -1232,7 +1232,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
if (cpu_family) if (cpu_family == CPU_HW_PSTATE)
dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", dprintk("cpu_init done, current fid 0x%x, did 0x%x\n",
data->currfid, data->currdid); data->currfid, data->currdid);
else else
......
...@@ -169,7 +169,9 @@ struct powernow_k8_data { ...@@ -169,7 +169,9 @@ struct powernow_k8_data {
#define MVS_MASK 3 #define MVS_MASK 3
#define VST_MASK 0x7f #define VST_MASK 0x7f
#define VID_MASK 0x1f #define VID_MASK 0x1f
#define FID_MASK 0x3f #define FID_MASK 0x1f
#define EXT_VID_MASK 0x3f
#define EXT_FID_MASK 0x3f
/* /*
......
...@@ -2,19 +2,15 @@ ...@@ -2,19 +2,15 @@
* cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
* M (part of the Centrino chipset). * M (part of the Centrino chipset).
* *
* Since the original Pentium M, most new Intel CPUs support Enhanced
* SpeedStep.
*
* Despite the "SpeedStep" in the name, this is almost entirely unlike * Despite the "SpeedStep" in the name, this is almost entirely unlike
* traditional SpeedStep. * traditional SpeedStep.
* *
* Modelled on speedstep.c * Modelled on speedstep.c
* *
* Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org> * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
*
* WARNING WARNING WARNING
*
* This driver manipulates the PERF_CTL MSR, which is only somewhat
* documented. While it seems to work on my laptop, it has not been
* tested anywhere else, and it may not work for you, do strange
* things or simply crash.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -36,7 +32,7 @@ ...@@ -36,7 +32,7 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#define PFX "speedstep-centrino: " #define PFX "speedstep-centrino: "
#define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>" #define MAINTAINER "cpufreq@lists.linux.org.uk"
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg) #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
......
...@@ -72,6 +72,14 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); ...@@ -72,6 +72,14 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
static unsigned int dbs_enable; /* number of CPUs using this policy */ static unsigned int dbs_enable; /* number of CPUs using this policy */
/*
* DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug
* lock and dbs_mutex. cpu_hotplug lock should always be held before
* dbs_mutex. If any function that can potentially take cpu_hotplug lock
* (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
* cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
* is recursive for the same process. -Venki
*/
static DEFINE_MUTEX (dbs_mutex); static DEFINE_MUTEX (dbs_mutex);
static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL);
...@@ -414,12 +422,14 @@ static void dbs_check_cpu(int cpu) ...@@ -414,12 +422,14 @@ static void dbs_check_cpu(int cpu)
static void do_dbs_timer(void *data) static void do_dbs_timer(void *data)
{ {
int i; int i;
lock_cpu_hotplug();
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
for_each_online_cpu(i) for_each_online_cpu(i)
dbs_check_cpu(i); dbs_check_cpu(i);
schedule_delayed_work(&dbs_work, schedule_delayed_work(&dbs_work,
usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
mutex_unlock(&dbs_mutex); mutex_unlock(&dbs_mutex);
unlock_cpu_hotplug();
} }
static inline void dbs_timer_init(void) static inline void dbs_timer_init(void)
...@@ -514,6 +524,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ...@@ -514,6 +524,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
break; break;
case CPUFREQ_GOV_LIMITS: case CPUFREQ_GOV_LIMITS:
lock_cpu_hotplug();
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
if (policy->max < this_dbs_info->cur_policy->cur) if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target( __cpufreq_driver_target(
...@@ -524,6 +535,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ...@@ -524,6 +535,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
this_dbs_info->cur_policy, this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L); policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex); mutex_unlock(&dbs_mutex);
unlock_cpu_hotplug();
break; break;
} }
return 0; return 0;
......
...@@ -71,6 +71,14 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); ...@@ -71,6 +71,14 @@ static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
static unsigned int dbs_enable; /* number of CPUs using this policy */ static unsigned int dbs_enable; /* number of CPUs using this policy */
/*
* DEADLOCK ALERT! There is a ordering requirement between cpu_hotplug
* lock and dbs_mutex. cpu_hotplug lock should always be held before
* dbs_mutex. If any function that can potentially take cpu_hotplug lock
* (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
* cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
* is recursive for the same process. -Venki
*/
static DEFINE_MUTEX (dbs_mutex); static DEFINE_MUTEX (dbs_mutex);
static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); static DECLARE_WORK (dbs_work, do_dbs_timer, NULL);
...@@ -363,12 +371,14 @@ static void dbs_check_cpu(int cpu) ...@@ -363,12 +371,14 @@ static void dbs_check_cpu(int cpu)
static void do_dbs_timer(void *data) static void do_dbs_timer(void *data)
{ {
int i; int i;
lock_cpu_hotplug();
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
for_each_online_cpu(i) for_each_online_cpu(i)
dbs_check_cpu(i); dbs_check_cpu(i);
queue_delayed_work(dbs_workq, &dbs_work, queue_delayed_work(dbs_workq, &dbs_work,
usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
mutex_unlock(&dbs_mutex); mutex_unlock(&dbs_mutex);
unlock_cpu_hotplug();
} }
static inline void dbs_timer_init(void) static inline void dbs_timer_init(void)
...@@ -469,6 +479,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ...@@ -469,6 +479,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
break; break;
case CPUFREQ_GOV_LIMITS: case CPUFREQ_GOV_LIMITS:
lock_cpu_hotplug();
mutex_lock(&dbs_mutex); mutex_lock(&dbs_mutex);
if (policy->max < this_dbs_info->cur_policy->cur) if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target( __cpufreq_driver_target(
...@@ -479,6 +490,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ...@@ -479,6 +490,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
this_dbs_info->cur_policy, this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L); policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex); mutex_unlock(&dbs_mutex);
unlock_cpu_hotplug();
break; break;
} }
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册