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

* git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] Add missing printk levels to e_powersaver
  [CPUFREQ] Fix sparse warning in powernow-k8
  [CPUFREQ] Support Model D parts and newer in e_powersaver
  [CPUFREQ] Powernow-k8: Update to support the latest Turion processors
  [CPUFREQ] fix configuration help message
  [CPUFREQ] powernow-k8 print pstate instead of fid/did for family 10h
  [CPUFREQ] Eliminate cpufreq_userspace scaling_setspeed deadlock
  [CPUFREQ] gx-suspmod.c: use boot_cpu_data instead of current_cpu_data
  [CPUFREQ] fix incorrect comment on show_available_freqs() in freq_table.c
  [CPUFREQ] drivers/cpufreq: Add missing "space"
  [CPUFREQ] arch/x86: Add missing "space"
  [CPUFREQ] Remove pointless Kconfig dependancy
This commit is contained in:
Linus Torvalds 2008-02-07 09:03:00 -08:00
commit 7a8c6ad918
11 changed files with 97 additions and 67 deletions

View File

@ -29,7 +29,7 @@ config X86_ACPI_CPUFREQ
config ELAN_CPUFREQ config ELAN_CPUFREQ
tristate "AMD Elan SC400 and SC410" tristate "AMD Elan SC400 and SC410"
select CPU_FREQ_TABLE select CPU_FREQ_TABLE
depends on X86_32 && X86_ELAN depends on X86_ELAN
---help--- ---help---
This adds the CPUFreq driver for AMD Elan SC400 and SC410 This adds the CPUFreq driver for AMD Elan SC400 and SC410
processors. processors.
@ -45,7 +45,7 @@ config ELAN_CPUFREQ
config SC520_CPUFREQ config SC520_CPUFREQ
tristate "AMD Elan SC520" tristate "AMD Elan SC520"
select CPU_FREQ_TABLE select CPU_FREQ_TABLE
depends on X86_32 && X86_ELAN depends on X86_ELAN
---help--- ---help---
This adds the CPUFreq driver for AMD Elan SC520 processor. This adds the CPUFreq driver for AMD Elan SC520 processor.

View File

@ -23,6 +23,7 @@
#define EPS_BRAND_C7 1 #define EPS_BRAND_C7 1
#define EPS_BRAND_EDEN 2 #define EPS_BRAND_EDEN 2
#define EPS_BRAND_C3 3 #define EPS_BRAND_C3 3
#define EPS_BRAND_C7D 4
struct eps_cpu_data { struct eps_cpu_data {
u32 fsb; u32 fsb;
@ -54,6 +55,7 @@ static int eps_set_state(struct eps_cpu_data *centaur,
{ {
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
u32 lo, hi; u32 lo, hi;
u8 current_multiplier, current_voltage;
int err = 0; int err = 0;
int i; int i;
@ -93,6 +95,15 @@ postchange:
rdmsr(MSR_IA32_PERF_STATUS, lo, hi); rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
freqs.new = centaur->fsb * ((lo >> 8) & 0xff); freqs.new = centaur->fsb * ((lo >> 8) & 0xff);
/* Print voltage and multiplier */
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
current_voltage = lo & 0xff;
printk(KERN_INFO "eps: Current voltage = %dmV\n",
current_voltage * 16 + 700);
current_multiplier = (lo >> 8) & 0xff;
printk(KERN_INFO "eps: Current multiplier = %d\n",
current_multiplier);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return err; return err;
} }
@ -141,9 +152,10 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
u8 current_multiplier, current_voltage; u8 current_multiplier, current_voltage;
u8 max_multiplier, max_voltage; u8 max_multiplier, max_voltage;
u8 min_multiplier, min_voltage; u8 min_multiplier, min_voltage;
u8 brand; u8 brand = 0;
u32 fsb; u32 fsb;
struct eps_cpu_data *centaur; struct eps_cpu_data *centaur;
struct cpuinfo_x86 *c = &cpu_data(0);
struct cpufreq_frequency_table *f_table; struct cpufreq_frequency_table *f_table;
int k, step, voltage; int k, step, voltage;
int ret; int ret;
@ -153,21 +165,36 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
return -ENODEV; return -ENODEV;
/* Check brand */ /* Check brand */
printk("eps: Detected VIA "); printk(KERN_INFO "eps: Detected VIA ");
switch (c->x86_model) {
case 10:
rdmsr(0x1153, lo, hi); rdmsr(0x1153, lo, hi);
brand = (((lo >> 2) ^ lo) >> 18) & 3; brand = (((lo >> 2) ^ lo) >> 18) & 3;
printk(KERN_CONT "Model A ");
break;
case 13:
rdmsr(0x1154, lo, hi);
brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff;
printk(KERN_CONT "Model D ");
break;
}
switch(brand) { switch(brand) {
case EPS_BRAND_C7M: case EPS_BRAND_C7M:
printk("C7-M\n"); printk(KERN_CONT "C7-M\n");
break; break;
case EPS_BRAND_C7: case EPS_BRAND_C7:
printk("C7\n"); printk(KERN_CONT "C7\n");
break; break;
case EPS_BRAND_EDEN: case EPS_BRAND_EDEN:
printk("Eden\n"); printk(KERN_CONT "Eden\n");
break;
case EPS_BRAND_C7D:
printk(KERN_CONT "C7-D\n");
break; break;
case EPS_BRAND_C3: case EPS_BRAND_C3:
printk("C3\n"); printk(KERN_CONT "C3\n");
return -ENODEV; return -ENODEV;
break; break;
} }
@ -179,7 +206,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
/* Can be locked at 0 */ /* Can be locked at 0 */
rdmsrl(MSR_IA32_MISC_ENABLE, val); rdmsrl(MSR_IA32_MISC_ENABLE, val);
if (!(val & 1 << 16)) { if (!(val & 1 << 16)) {
printk("eps: Can't enable Enhanced PowerSaver\n"); printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n");
return -ENODEV; return -ENODEV;
} }
} }
@ -187,19 +214,19 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
/* Print voltage and multiplier */ /* Print voltage and multiplier */
rdmsr(MSR_IA32_PERF_STATUS, lo, hi); rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
current_voltage = lo & 0xff; current_voltage = lo & 0xff;
printk("eps: Current voltage = %dmV\n", current_voltage * 16 + 700); printk(KERN_INFO "eps: Current voltage = %dmV\n", current_voltage * 16 + 700);
current_multiplier = (lo >> 8) & 0xff; current_multiplier = (lo >> 8) & 0xff;
printk("eps: Current multiplier = %d\n", current_multiplier); printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier);
/* Print limits */ /* Print limits */
max_voltage = hi & 0xff; max_voltage = hi & 0xff;
printk("eps: Highest voltage = %dmV\n", max_voltage * 16 + 700); printk(KERN_INFO "eps: Highest voltage = %dmV\n", max_voltage * 16 + 700);
max_multiplier = (hi >> 8) & 0xff; max_multiplier = (hi >> 8) & 0xff;
printk("eps: Highest multiplier = %d\n", max_multiplier); printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier);
min_voltage = (hi >> 16) & 0xff; min_voltage = (hi >> 16) & 0xff;
printk("eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700); printk(KERN_INFO "eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700);
min_multiplier = (hi >> 24) & 0xff; min_multiplier = (hi >> 24) & 0xff;
printk("eps: Lowest multiplier = %d\n", min_multiplier); printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier);
/* Sanity checks */ /* Sanity checks */
if (current_multiplier == 0 || max_multiplier == 0 if (current_multiplier == 0 || max_multiplier == 0
@ -208,7 +235,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
if (current_multiplier > max_multiplier if (current_multiplier > max_multiplier
|| max_multiplier <= min_multiplier) || max_multiplier <= min_multiplier)
return -EINVAL; return -EINVAL;
if (current_voltage > 0x1c || max_voltage > 0x1c) if (current_voltage > 0x1f || max_voltage > 0x1f)
return -EINVAL; return -EINVAL;
if (max_voltage < min_voltage) if (max_voltage < min_voltage)
return -EINVAL; return -EINVAL;
@ -310,7 +337,7 @@ static int __init eps_init(void)
/* This driver will work only on Centaur C7 processors with /* This driver will work only on Centaur C7 processors with
* Enhanced SpeedStep/PowerSaver registers */ * Enhanced SpeedStep/PowerSaver registers */
if (c->x86_vendor != X86_VENDOR_CENTAUR if (c->x86_vendor != X86_VENDOR_CENTAUR
|| c->x86 != 6 || c->x86_model != 10) || c->x86 != 6 || c->x86_model < 10)
return -ENODEV; return -ENODEV;
if (!cpu_has(c, X86_FEATURE_EST)) if (!cpu_has(c, X86_FEATURE_EST))
return -ENODEV; return -ENODEV;

View File

@ -181,8 +181,8 @@ static __init struct pci_dev *gx_detect_chipset(void)
struct pci_dev *gx_pci = NULL; struct pci_dev *gx_pci = NULL;
/* check if CPU is a MediaGX or a Geode. */ /* check if CPU is a MediaGX or a Geode. */
if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
(current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
dprintk("error: no MediaGX/Geode processor found!\n"); dprintk("error: no MediaGX/Geode processor found!\n");
return NULL; return NULL;
} }

View File

@ -578,10 +578,9 @@ static void print_basics(struct powernow_k8_data *data)
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 == CPU_HW_PSTATE) { if (cpu_family == CPU_HW_PSTATE) {
printk(KERN_INFO PFX " %d : fid 0x%x did 0x%x (%d MHz)\n", printk(KERN_INFO PFX " %d : pstate %d (%d MHz)\n",
j, j,
(data->powernow_table[j].index & 0xff00) >> 8, data->powernow_table[j].index,
(data->powernow_table[j].index & 0xff0000) >> 16,
data->powernow_table[j].frequency/1000); data->powernow_table[j].frequency/1000);
} else { } else {
printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n",
@ -1235,8 +1234,10 @@ static unsigned int powernowk8_get (unsigned int cpu)
struct powernow_k8_data *data; struct powernow_k8_data *data;
cpumask_t oldmask = current->cpus_allowed; cpumask_t oldmask = current->cpus_allowed;
unsigned int khz = 0; unsigned int khz = 0;
unsigned int first;
data = per_cpu(powernow_data, first_cpu(per_cpu(cpu_core_map, cpu))); first = first_cpu(per_cpu(cpu_core_map, cpu));
data = per_cpu(powernow_data, first);
if (!data) if (!data)
return -EINVAL; return -EINVAL;

View File

@ -47,7 +47,7 @@ struct powernow_k8_data {
#define CPUID_XFAM 0x0ff00000 /* extended family */ #define CPUID_XFAM 0x0ff00000 /* extended family */
#define CPUID_XFAM_K8 0 #define CPUID_XFAM_K8 0
#define CPUID_XMOD 0x000f0000 /* extended model */ #define CPUID_XMOD 0x000f0000 /* extended model */
#define CPUID_XMOD_REV_MASK 0x00080000 #define CPUID_XMOD_REV_MASK 0x000c0000
#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ #define CPUID_XFAM_10H 0x00100000 /* family 0x10 */
#define CPUID_USE_XFAM_XMOD 0x00000f00 #define CPUID_USE_XFAM_XMOD 0x00000f00
#define CPUID_GET_MAX_CAPABILITIES 0x80000000 #define CPUID_GET_MAX_CAPABILITIES 0x80000000

View File

@ -9,9 +9,6 @@ config CPU_FREQ
clock speed, you need to either enable a dynamic cpufreq governor clock speed, you need to either enable a dynamic cpufreq governor
(see below) after boot, or use a userspace tool. (see below) after boot, or use a userspace tool.
To compile this driver as a module, choose M here: the
module will be called cpufreq.
For details, take a look at <file:Documentation/cpu-freq>. For details, take a look at <file:Documentation/cpu-freq>.
If in doubt, say N. If in doubt, say N.

View File

@ -601,6 +601,31 @@ static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
return i; return i;
} }
static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
const char *buf, size_t count)
{
unsigned int freq = 0;
unsigned int ret;
if (!policy->governor->store_setspeed)
return -EINVAL;
ret = sscanf(buf, "%u", &freq);
if (ret != 1)
return -EINVAL;
policy->governor->store_setspeed(policy, freq);
return count;
}
static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
{
if (!policy->governor->show_setspeed)
return sprintf(buf, "<unsupported>\n");
return policy->governor->show_setspeed(policy, buf);
}
#define define_one_ro(_name) \ #define define_one_ro(_name) \
static struct freq_attr _name = \ static struct freq_attr _name = \
@ -624,6 +649,7 @@ define_one_ro(affected_cpus);
define_one_rw(scaling_min_freq); define_one_rw(scaling_min_freq);
define_one_rw(scaling_max_freq); define_one_rw(scaling_max_freq);
define_one_rw(scaling_governor); define_one_rw(scaling_governor);
define_one_rw(scaling_setspeed);
static struct attribute * default_attrs[] = { static struct attribute * default_attrs[] = {
&cpuinfo_min_freq.attr, &cpuinfo_min_freq.attr,
@ -634,6 +660,7 @@ static struct attribute * default_attrs[] = {
&scaling_governor.attr, &scaling_governor.attr,
&scaling_driver.attr, &scaling_driver.attr,
&scaling_available_governors.attr, &scaling_available_governors.attr,
&scaling_setspeed.attr,
NULL NULL
}; };

View File

@ -65,12 +65,12 @@ static struct notifier_block userspace_cpufreq_notifier_block = {
/** /**
* cpufreq_set - set the CPU frequency * cpufreq_set - set the CPU frequency
* @policy: pointer to policy struct where freq is being set
* @freq: target frequency in kHz * @freq: target frequency in kHz
* @cpu: CPU for which the frequency is to be set
* *
* Sets the CPU frequency to freq. * Sets the CPU frequency to freq.
*/ */
static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
{ {
int ret = -EINVAL; int ret = -EINVAL;
@ -102,34 +102,11 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy)
} }
/************************** sysfs interface ************************/
static ssize_t show_speed(struct cpufreq_policy *policy, char *buf) static ssize_t show_speed(struct cpufreq_policy *policy, char *buf)
{ {
return sprintf(buf, "%u\n", cpu_cur_freq[policy->cpu]); return sprintf(buf, "%u\n", cpu_cur_freq[policy->cpu]);
} }
static ssize_t
store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
{
unsigned int freq = 0;
unsigned int ret;
ret = sscanf (buf, "%u", &freq);
if (ret != 1)
return -EINVAL;
cpufreq_set(freq, policy);
return count;
}
static struct freq_attr freq_attr_scaling_setspeed =
{
.attr = { .name = "scaling_setspeed", .mode = 0644 },
.show = show_speed,
.store = store_speed,
};
static int cpufreq_governor_userspace(struct cpufreq_policy *policy, static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
unsigned int event) unsigned int event)
{ {
@ -142,10 +119,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
return -EINVAL; return -EINVAL;
BUG_ON(!policy->cur); BUG_ON(!policy->cur);
mutex_lock(&userspace_mutex); mutex_lock(&userspace_mutex);
rc = sysfs_create_file (&policy->kobj,
&freq_attr_scaling_setspeed.attr);
if (rc)
goto start_out;
if (cpus_using_userspace_governor == 0) { if (cpus_using_userspace_governor == 0) {
cpufreq_register_notifier( cpufreq_register_notifier(
@ -160,7 +133,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_cur_freq[cpu] = policy->cur; cpu_cur_freq[cpu] = policy->cur;
cpu_set_freq[cpu] = policy->cur; cpu_set_freq[cpu] = policy->cur;
dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
start_out:
mutex_unlock(&userspace_mutex); mutex_unlock(&userspace_mutex);
break; break;
case CPUFREQ_GOV_STOP: case CPUFREQ_GOV_STOP:
@ -176,7 +149,6 @@ start_out:
cpu_min_freq[cpu] = 0; cpu_min_freq[cpu] = 0;
cpu_max_freq[cpu] = 0; cpu_max_freq[cpu] = 0;
cpu_set_freq[cpu] = 0; cpu_set_freq[cpu] = 0;
sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
dprintk("managing cpu %u stopped\n", cpu); dprintk("managing cpu %u stopped\n", cpu);
mutex_unlock(&userspace_mutex); mutex_unlock(&userspace_mutex);
break; break;
@ -211,6 +183,8 @@ start_out:
struct cpufreq_governor cpufreq_gov_userspace = { struct cpufreq_governor cpufreq_gov_userspace = {
.name = "userspace", .name = "userspace",
.governor = cpufreq_governor_userspace, .governor = cpufreq_governor_userspace,
.store_setspeed = cpufreq_set,
.show_setspeed = show_speed,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
EXPORT_SYMBOL(cpufreq_gov_userspace); EXPORT_SYMBOL(cpufreq_gov_userspace);

View File

@ -171,7 +171,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
static struct cpufreq_frequency_table *show_table[NR_CPUS]; static struct cpufreq_frequency_table *show_table[NR_CPUS];
/** /**
* show_scaling_governor - show the current policy for the specified CPU * show_available_freqs - show available frequencies for the specified CPU
*/ */
static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf) static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
{ {

View File

@ -167,6 +167,10 @@ struct cpufreq_governor {
char name[CPUFREQ_NAME_LEN]; char name[CPUFREQ_NAME_LEN];
int (*governor) (struct cpufreq_policy *policy, int (*governor) (struct cpufreq_policy *policy,
unsigned int event); unsigned int event);
ssize_t (*show_setspeed) (struct cpufreq_policy *policy,
char *buf);
int (*store_setspeed) (struct cpufreq_policy *policy,
unsigned int freq);
unsigned int max_transition_latency; /* HW must be able to switch to unsigned int max_transition_latency; /* HW must be able to switch to
next freq faster than this value in nano secs or we next freq faster than this value in nano secs or we
will fallback to performance governor */ will fallback to performance governor */