#ifdef CONFIG_X86_POWERNOW_K8_ACPI
#include <linux/acpi.h>
-#include <linux/mutex.h>
#include <acpi/processor.h>
#endif
#define PFX "powernow-k8: "
#define BFX PFX "BIOS error: "
-#define VERSION "version 1.60.2"
+#define VERSION "version 1.60.0"
#include "powernow-k8.h"
/* serialize freq changes */
-static DEFINE_MUTEX(fidvid_mutex);
+static DECLARE_MUTEX(fidvid_sem);
static struct powernow_k8_data *powernow_data[NR_CPUS];
*/
static u32 convert_fid_to_vco_fid(u32 fid)
{
- if (fid < HI_FID_TABLE_BOTTOM)
+ if (fid < HI_FID_TABLE_BOTTOM) {
return 8 + (2 * fid);
- else
+ } else {
return fid;
+ }
}
/*
if (i++ > 100) {
printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
return 1;
- }
+ }
} while (query_current_values_with_pending_wait(data));
count_off_irt(data);
goto out;
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
- if ((eax & CPUID_XFAM) != CPUID_XFAM_K8)
- goto out;
-
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
+ ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
goto out;
/* 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 both entries are the same, ignore this
+ * one...
+ */
if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
(powernow_table[i].index != powernow_table[cntlofreq].index)) {
printk(KERN_ERR PFX "Too many lo freq table entries\n");
dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
/* fid are the lower 8 bits of the index we stored into
- * the cpufreq frequency table in find_psb_table, vid are
+ * the cpufreq frequency table in find_psb_table, vid are
* the upper 8 bits.
*/
{
cpumask_t oldmask = CPU_MASK_ALL;
struct powernow_k8_data *data = powernow_data[pol->cpu];
- u32 checkfid;
- u32 checkvid;
+ u32 checkfid = data->currfid;
+ u32 checkvid = data->currvid;
unsigned int newstate;
int ret = -EIO;
-
- if (!data)
- return -EINVAL;
-
- checkfid = data->currfid;
- checkvid = data->currvid;
+ int i;
/* only run on specific CPU from here on */
oldmask = current->cpus_allowed;
if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
goto err_out;
- mutex_lock(&fidvid_mutex);
+ down(&fidvid_sem);
powernow_k8_acpi_pst_values(data, newstate);
if (transition_frequency(data, newstate)) {
printk(KERN_ERR PFX "transition frequency failed\n");
ret = 1;
- mutex_unlock(&fidvid_mutex);
+ up(&fidvid_sem);
goto err_out;
}
- mutex_unlock(&fidvid_mutex);
+
+ /* Update all the fid/vids of our siblings */
+ for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+ powernow_data[i]->currvid = data->currvid;
+ powernow_data[i]->currfid = data->currfid;
+ }
+ up(&fidvid_sem);
pol->cur = find_khz_freq_from_fid(data->currfid);
ret = 0;
{
struct powernow_k8_data *data = powernow_data[pol->cpu];
- if (!data)
- return -EINVAL;
-
return cpufreq_frequency_table_verify(pol, data->powernow_table);
}
{
struct powernow_k8_data *data;
cpumask_t oldmask = CPU_MASK_ALL;
- int rc;
+ int rc, i;
if (!cpu_online(pol->cpu))
return -ENODEV;
pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
pol->cpus = cpu_core_map[pol->cpu];
- /* Take a crude guess here.
+ /* 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;
printk("cpu_init done, current fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
- powernow_data[pol->cpu] = data;
+ for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+ powernow_data[i] = data;
+ }
return 0;
static unsigned int powernowk8_get (unsigned int cpu)
{
- struct powernow_k8_data *data;
+ struct powernow_k8_data *data = powernow_data[cpu];
cpumask_t oldmask = current->cpus_allowed;
unsigned int khz = 0;
- data = powernow_data[first_cpu(cpu_core_map[cpu])];
-
- if (!data)
- return -EINVAL;
-
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu) {
printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu);
{
unsigned int i, supported_cpus = 0;
- for_each_online_cpu(i) {
+ for (i=0; i<NR_CPUS; i++) {
+ if (!cpu_online(i))
+ continue;
if (check_supported_cpu(i))
supported_cpus++;
}
if (supported_cpus == num_online_cpus()) {
- printk(KERN_INFO PFX "Found %d AMD Athlon 64 / Opteron "
- "processors (" VERSION ")\n", supported_cpus);
+ printk(KERN_INFO PFX "Found %d AMD Athlon 64 / Opteron processors (" VERSION ")\n",
+ supported_cpus);
return cpufreq_register_driver(&cpufreq_amd64_driver);
}