Browse Source

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
Linus Torvalds 17 years ago
parent
commit
7a8c6ad918

+ 2 - 2
arch/x86/kernel/cpu/cpufreq/Kconfig

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

+ 44 - 17
arch/x86/kernel/cpu/cpufreq/e_powersaver.c

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

+ 2 - 2
arch/x86/kernel/cpu/cpufreq/gx-suspmod.c

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

+ 1 - 1
arch/x86/kernel/cpu/cpufreq/powernow-k7.c

@@ -460,7 +460,7 @@ static int powernow_decode_bios (int maxfid, int startvid)
 
 			latency = psb->settlingtime;
 			if (latency < 100) {
-				printk (KERN_INFO PFX "BIOS set settling time to %d microseconds."
+				printk(KERN_INFO PFX "BIOS set settling time to %d microseconds. "
 						"Should be at least 100. Correcting.\n", latency);
 				latency = 100;
 			}

+ 5 - 4
arch/x86/kernel/cpu/cpufreq/powernow-k8.c

@@ -578,10 +578,9 @@ static void print_basics(struct powernow_k8_data *data)
 	for (j = 0; j < data->numps; j++) {
 		if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) {
 			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,
-					(data->powernow_table[j].index & 0xff00) >> 8,
-					(data->powernow_table[j].index & 0xff0000) >> 16,
+					data->powernow_table[j].index,
 					data->powernow_table[j].frequency/1000);
 			} else {
 				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;
 	cpumask_t oldmask = current->cpus_allowed;
 	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)
 		return -EINVAL;

+ 1 - 1
arch/x86/kernel/cpu/cpufreq/powernow-k8.h

@@ -47,7 +47,7 @@ struct powernow_k8_data {
 #define CPUID_XFAM			0x0ff00000	/* extended family */
 #define CPUID_XFAM_K8			0
 #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_USE_XFAM_XMOD		0x00000f00
 #define CPUID_GET_MAX_CAPABILITIES	0x80000000

+ 0 - 3
drivers/cpufreq/Kconfig

@@ -9,9 +9,6 @@ config CPU_FREQ
 	  clock speed, you need to either enable a dynamic cpufreq governor
 	  (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>.
 
 	  If in doubt, say N.

+ 30 - 3
drivers/cpufreq/cpufreq.c

@@ -287,7 +287,7 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
 	if (!l_p_j_ref_freq) {
 		l_p_j_ref = loops_per_jiffy;
 		l_p_j_ref_freq = ci->old;
-		dprintk("saving %lu as reference value for loops_per_jiffy;"
+		dprintk("saving %lu as reference value for loops_per_jiffy; "
 			"freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
 	}
 	if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
@@ -295,7 +295,7 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
 	    (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
 		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
 								ci->new);
-		dprintk("scaling loops_per_jiffy to %lu"
+		dprintk("scaling loops_per_jiffy to %lu "
 			"for frequency %u kHz\n", loops_per_jiffy, ci->new);
 	}
 }
@@ -601,6 +601,31 @@ static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
 	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) \
 static struct freq_attr _name = \
@@ -624,6 +649,7 @@ define_one_ro(affected_cpus);
 define_one_rw(scaling_min_freq);
 define_one_rw(scaling_max_freq);
 define_one_rw(scaling_governor);
+define_one_rw(scaling_setspeed);
 
 static struct attribute * default_attrs[] = {
 	&cpuinfo_min_freq.attr,
@@ -634,6 +660,7 @@ static struct attribute * default_attrs[] = {
 	&scaling_governor.attr,
 	&scaling_driver.attr,
 	&scaling_available_governors.attr,
+	&scaling_setspeed.attr,
 	NULL
 };
 
@@ -1313,7 +1340,7 @@ static int cpufreq_resume(struct sys_device * sysdev)
 			struct cpufreq_freqs freqs;
 
 			if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-				dprintk("Warning: CPU frequency"
+				dprintk("Warning: CPU frequency "
 				       "is %u, cpufreq assumed %u kHz.\n",
 				       cur_freq, cpu_policy->cur);
 

+ 7 - 33
drivers/cpufreq/cpufreq_userspace.c

@@ -65,12 +65,12 @@ static struct notifier_block userspace_cpufreq_notifier_block = {
 
 /**
  * cpufreq_set - set the CPU frequency
+ * @policy: pointer to policy struct where freq is being set
  * @freq: target frequency in kHz
- * @cpu: CPU for which the frequency is to be set
  *
  * 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;
 
@@ -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,
 				   unsigned int event)
 {
@@ -142,10 +119,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
 			return -EINVAL;
 		BUG_ON(!policy->cur);
 		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) {
 			cpufreq_register_notifier(
@@ -160,7 +133,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
 		cpu_cur_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]);
-start_out:
+
 		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_STOP:
@@ -176,7 +149,6 @@ start_out:
 		cpu_min_freq[cpu] = 0;
 		cpu_max_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);
 		mutex_unlock(&userspace_mutex);
 		break;
@@ -211,6 +183,8 @@ start_out:
 struct cpufreq_governor cpufreq_gov_userspace = {
 	.name		= "userspace",
 	.governor	= cpufreq_governor_userspace,
+	.store_setspeed	= cpufreq_set,
+	.show_setspeed	= show_speed,
 	.owner		= THIS_MODULE,
 };
 EXPORT_SYMBOL(cpufreq_gov_userspace);

+ 1 - 1
drivers/cpufreq/freq_table.c

@@ -171,7 +171,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
 
 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)
 {

+ 4 - 0
include/linux/cpufreq.h

@@ -167,6 +167,10 @@ struct cpufreq_governor {
 	char	name[CPUFREQ_NAME_LEN];
 	int 	(*governor)	(struct cpufreq_policy *policy,
 				 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
 			next freq faster than this value in nano secs or we
 			will fallback to performance governor */