Skip to content

Commit

Permalink
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…davej/cpufreq

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] Fix NULL ptr regression in powernow-k8
  [CPUFREQ] Create a blacklist for processors that should not load the acpi-cpufreq module.
  [CPUFREQ] Powernow-k8: Enable more than 2 low P-states
  [CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)
  [CPUFREQ] ondemand - Use global sysfs dir for tuning settings
  [CPUFREQ] Introduce global, not per core: /sys/devices/system/cpu/cpufreq
  [CPUFREQ] Bail out of cpufreq_add_dev if the link for a managed CPU got created
  [CPUFREQ] Factor out policy setting from cpufreq_add_dev
  [CPUFREQ] Factor out interface creation from cpufreq_add_dev
  [CPUFREQ] Factor out symlink creation from cpufreq_add_dev
  [CPUFREQ] cleanup up -ENOMEM handling in cpufreq_add_dev
  [CPUFREQ] Reduce scope of cpu_sys_dev in cpufreq_add_dev
  [CPUFREQ] update Doc for cpuinfo_cur_freq and scaling_cur_freq
  • Loading branch information
Linus Torvalds committed Sep 18, 2009
2 parents a03fdb7 + f0adb13 commit 714af06
Show file tree
Hide file tree
Showing 6 changed files with 350 additions and 178 deletions.
9 changes: 7 additions & 2 deletions Documentation/cpu-freq/user-guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ scaling_governor, and by "echoing" the name of another
work on some specific architectures or
processors.

cpuinfo_cur_freq : Current speed of the CPU, in KHz.
cpuinfo_cur_freq : Current frequency of the CPU as obtained from
the hardware, in KHz. This is the frequency
the CPU actually runs at.

scaling_available_frequencies : List of available frequencies, in KHz.

Expand All @@ -196,7 +198,10 @@ related_cpus : List of CPUs that need some sort of frequency

scaling_driver : Hardware driver for cpufreq.

scaling_cur_freq : Current frequency of the CPU, in KHz.
scaling_cur_freq : Current frequency of the CPU as determined by
the governor and cpufreq core, in KHz. This is
the frequency the kernel thinks the CPU runs
at.

If you have selected the "userspace" governor which allows you to
set the CPU operating frequency to a specific value, you can read out
Expand Down
21 changes: 21 additions & 0 deletions arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = {
},
{ }
};

static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
{
/* http://www.intel.com/Assets/PDF/specupdate/314554.pdf
* AL30: A Machine Check Exception (MCE) Occurring during an
* Enhanced Intel SpeedStep Technology Ratio Change May Cause
* Both Processor Cores to Lock Up when HT is enabled*/
if (c->x86_vendor == X86_VENDOR_INTEL) {
if ((c->x86 == 15) &&
(c->x86_model == 6) &&
(c->x86_mask == 8) && smt_capable())
return -ENODEV;
}
return 0;
}
#endif

static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
Expand All @@ -540,6 +555,12 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)

dprintk("acpi_cpufreq_cpu_init\n");

#ifdef CONFIG_SMP
result = acpi_cpufreq_blacklist(c);
if (result)
return result;
#endif

data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
Expand Down
44 changes: 12 additions & 32 deletions arch/x86/kernel/cpu/cpufreq/powernow-k8.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,10 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
return 0;
}

static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
unsigned int entry)
{
data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
}

static void print_basics(struct powernow_k8_data *data)
Expand Down Expand Up @@ -854,6 +855,10 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
goto err_out;
}

/* fill in data */
data->numps = data->acpi_data.state_count;
powernow_k8_acpi_pst_values(data, 0);

if (cpu_family == CPU_HW_PSTATE)
ret_val = fill_powernow_table_pstate(data, powernow_table);
else
Expand All @@ -866,11 +871,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
powernow_table[data->acpi_data.state_count].index = 0;
data->powernow_table = powernow_table;

/* fill in data */
data->numps = data->acpi_data.state_count;
if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
print_basics(data);
powernow_k8_acpi_pst_values(data, 0);

/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);
Expand Down Expand Up @@ -914,13 +916,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
"bad value %d.\n", i, index);
printk(KERN_ERR PFX "Please report to BIOS "
"manufacturer\n");
invalidate_entry(data, i);
invalidate_entry(powernow_table, i);
continue;
}
rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
if (!(hi & HW_PSTATE_VALID_MASK)) {
dprintk("invalid pstate %d, ignoring\n", index);
invalidate_entry(data, i);
invalidate_entry(powernow_table, i);
continue;
}

Expand All @@ -941,7 +943,6 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
struct cpufreq_frequency_table *powernow_table)
{
int i;
int cntlofreq = 0;

for (i = 0; i < data->acpi_data.state_count; i++) {
u32 fid;
Expand Down Expand Up @@ -970,46 +971,25 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
/* verify frequency is OK */
if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
dprintk("invalid freq %u kHz, ignoring\n", freq);
invalidate_entry(data, i);
invalidate_entry(powernow_table, i);
continue;
}

/* verify voltage is OK -
* BIOSs are using "off" to indicate invalid */
if (vid == VID_OFF) {
dprintk("invalid vid %u, ignoring\n", vid);
invalidate_entry(data, i);
invalidate_entry(powernow_table, i);
continue;
}

/* verify only 1 entry from the lo frequency table */
if (fid < HI_FID_TABLE_BOTTOM) {
if (cntlofreq) {
/* if both entries are the same,
* ignore this one ... */
if ((freq != powernow_table[cntlofreq].frequency) ||
(index != powernow_table[cntlofreq].index)) {
printk(KERN_ERR PFX
"Too many lo freq table "
"entries\n");
return 1;
}

dprintk("double low frequency table entry, "
"ignoring it.\n");
invalidate_entry(data, i);
continue;
} else
cntlofreq = i;
}

if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
printk(KERN_INFO PFX "invalid freq entries "
"%u kHz vs. %u kHz\n", freq,
(unsigned int)
(data->acpi_data.states[i].core_frequency
* 1000));
invalidate_entry(data, i);
invalidate_entry(powernow_table, i);
continue;
}
}
Expand Down
Loading

0 comments on commit 714af06

Please sign in to comment.