cpufreq Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Dominik Brodowski <linux@brodo.de>
To: davej@codemonkey.org.uk, cpufreq@www.linux.org.uk
Subject: [RFC] remove special-handling of longrun
Date: Tue, 4 Nov 2003 22:30:15 +0100	[thread overview]
Message-ID: <20031104213015.GA7175@brodo.de> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 12995 bytes --]

[Note: this is definitely nothing for 2.6.0-testX]

- Remove the current ->setpolicy implementation.
- A cpufreq driver should be able to define a 
	->target function if the CPU can be set to a specific operating frequency,
  or a  ->range  function if the CPU can be set to an area of operating
		 frequencies, where the CPU decides on its own which one to
		 chose.
- Also "->target" CPUfreq implementations may be able to provide a generic
  "economy" / "performance" / "burst" / ... mode, and such setting is best
  done as an extra sysfs parameter. So, move the longrun operating mode
  setting to such an extra sysfs file.

	Dominik


diff -ruN linux-original/arch/i386/kernel/cpu/cpufreq/longrun.c linux/arch/i386/kernel/cpu/cpufreq/longrun.c
--- linux-original/arch/i386/kernel/cpu/cpufreq/longrun.c	2003-11-04 15:27:33.000000000 +0100
+++ linux/arch/i386/kernel/cpu/cpufreq/longrun.c	2003-11-04 21:08:43.000000000 +0100
@@ -16,8 +16,6 @@
 #include <asm/processor.h>
 #include <asm/timex.h>
 
-static struct cpufreq_driver	longrun_driver;
-
 /**
  * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz 
  * values into per cent values. In TMTA microcode, the following is valid:
@@ -30,19 +28,12 @@
  * longrun_get_policy - get the current LongRun policy
  * @policy: struct cpufreq_policy where current policy is written into
  *
- * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS
- * and MSR_TMTA_LONGRUN_CTRL
+ * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_CTRL
  */
 static void longrun_get_policy(struct cpufreq_policy *policy)
 {
 	u32 msr_lo, msr_hi;
 
-	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
-	if (msr_lo & 0x01)
-		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-	else
-		policy->policy = CPUFREQ_POLICY_POWERSAVE;
-	
 	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
 	msr_lo &= 0x0000007F;
 	msr_hi &= 0x0000007F;
@@ -80,18 +71,6 @@
 	if (pctg_lo > pctg_hi)
 		pctg_lo = pctg_hi;
 
-	/* performance or economy mode */
-	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
-	msr_lo &= 0xFFFFFFFE;
-	switch (policy->policy) {
-	case CPUFREQ_POLICY_PERFORMANCE:
-		msr_lo |= 0x00000001;
-		break;
-	case CPUFREQ_POLICY_POWERSAVE:
-		break;
-	}
-	wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
-
 	/* lower and upper boundary */
 	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
 	msr_lo &= 0xFFFFFF80;
@@ -112,18 +91,13 @@
  */
 static int longrun_verify_policy(struct cpufreq_policy *policy)
 {
-	if (!policy)
+	if (!policy || !(policy->cpu != 0))
 		return -EINVAL;
 
-	policy->cpu = 0;
 	cpufreq_verify_within_limits(policy, 
 		policy->cpuinfo.min_freq, 
 		policy->cpuinfo.max_freq);
 
-	if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
-	    (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
-		return -EINVAL;
-
 	return 0;
 }
 
@@ -243,12 +217,69 @@
 }
 
 
+/*
+ * The TMTA CPU can be put into two modes: economy mode or
+ * performance mode.
+ */
+
+static ssize_t show_longrun_mode (struct cpufreq_policy *policy, char *buf)
+{
+
+	u32 msr_lo, msr_hi;
+
+	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
+	if (msr_lo & 0x01)
+		return sprintf(buf, "performance\n");
+	else
+		return sprintf(buf, "economy\n");
+}
+
+static ssize_t store_longrun_mode (struct cpufreq_policy * policy, 
+				   const char *buf, size_t count) 
+{
+	u32 mode = 0xFF;
+	u32 msr_lo, msr_hi;
+
+	if (count < 7)
+		return -EINVAL;
+
+	if (!strnicmp(buf,"performance",7))
+		mode = 0x01;
+	if (!strnicmp(buf,"economy",7))
+		mode = 0x00;
+
+	if (mode == 0xFF)
+		return -EINVAL;
+
+	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
+
+	msr_lo &= 0xFFFFFFFE;
+	msr_lo |= mode;
+
+	wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
+
+	return count;
+}
+
+
+struct freq_attr longrun_mode_attr = {
+	.attr = { .name = "lognrun_mode", .mode = 0644 },
+	.show = show_longrun_mode,
+	.store = store_longrun_mode,
+};
+
+static struct freq_attr* longrun_attr[] = {
+	&longrun_mode_attr,
+	NULL,
+};
+
 static struct cpufreq_driver longrun_driver = {
 	.verify 	= longrun_verify_policy,
-	.setpolicy 	= longrun_set_policy,
+	.range		= longrun_set_policy,
 	.init		= longrun_cpu_init,
 	.name		= "longrun",
 	.owner		= THIS_MODULE,
+	.attr		= longrun_attr,
 };
 
 
diff -ruN linux-original/drivers/cpufreq/cpufreq.c linux/drivers/cpufreq/cpufreq.c
--- linux-original/drivers/cpufreq/cpufreq.c	2003-11-04 15:27:37.000000000 +0100
+++ linux/drivers/cpufreq/cpufreq.c	2003-11-04 22:20:20.224386984 +0100
@@ -105,35 +105,28 @@
 /**
  * cpufreq_parse_governor - parse a governor string
  */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
-				struct cpufreq_governor **governor)
+int cpufreq_parse_governor (char *str_governor, 
+struct cpufreq_governor **governor)
 {
+	struct cpufreq_governor *t;
+
 	if (!cpufreq_driver)
 		return -EINVAL;
-	if (cpufreq_driver->setpolicy) {
-		if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
-			*policy = CPUFREQ_POLICY_PERFORMANCE;
-			return 0;
-		} else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
-			*policy = CPUFREQ_POLICY_POWERSAVE;
+
+	if (cpufreq_driver->range) {
+		*governor = NULL;
+		return 0;
+	}
+
+	down(&cpufreq_governor_sem);
+	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
+		if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
+			*governor = t;
+			up(&cpufreq_governor_sem);
 			return 0;
 		}
-		return -EINVAL;
-	} else {
-		struct cpufreq_governor *t;
-		down(&cpufreq_governor_sem);
-		if (!cpufreq_driver || !cpufreq_driver->target)
-			goto out;
-		list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
-			if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
-				*governor = t;
-				up(&cpufreq_governor_sem);
-				return 0;
-			}
-		}
-	out:
-		up(&cpufreq_governor_sem);
 	}
+	up(&cpufreq_governor_sem);
 	return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(cpufreq_parse_governor);
@@ -193,11 +186,7 @@
  */
 static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf)
 {
-	if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
-		return sprintf(buf, "powersave\n");
-	else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
-		return sprintf(buf, "performance\n");
-	else if (policy->governor)
+	if (policy->governor)
 		return snprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
 	return -EINVAL;
 }
@@ -221,7 +210,7 @@
 	if (ret != 1)
 		return -EINVAL;
 
-	if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor))
+	if (cpufreq_parse_governor(str_governor, &new_policy.governor))
 		return -EINVAL;
 
 	ret = cpufreq_set_policy(&new_policy);
@@ -246,11 +235,6 @@
 	ssize_t i = 0;
 	struct cpufreq_governor *t;
 
-	if (!cpufreq_driver->target) {
-		i += sprintf(buf, "performance powersave");
-		goto out;
-	}
-
 	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
 		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
 			goto out;
@@ -288,9 +272,7 @@
 	&cpuinfo_max_freq.attr,
 	&scaling_min_freq.attr,
 	&scaling_max_freq.attr,
-	&scaling_governor.attr,
 	&scaling_driver.attr,
-	&scaling_available_governors.attr,
 	NULL
 };
 
@@ -387,6 +369,11 @@
 		goto err_out;
 
 	/* set up files for this cpu device */
+	if (cpufreq_driver->target) {
+		sysfs_create_file(&policy->kobj, &scaling_governor.attr);
+		sysfs_create_file(&policy->kobj, &scaling_available_governors.attr);
+	}
+
 	drv_attr = cpufreq_driver->attr;
 	while ((drv_attr) && (*drv_attr)) {
 		sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
@@ -501,8 +488,8 @@
 		goto out;
 	}
 
-	if (cpufreq_driver->setpolicy)
-		ret = cpufreq_driver->setpolicy(cpu_policy);
+	if (cpufreq_driver->range)
+		ret = cpufreq_driver->range(cpu_policy);
 	else
 	/* CPUFREQ_RELATION_H or CPUFREQ_RELATION_L have the same effect here, as cpu_policy->cur is known
 	 * to be a valid and exact target frequency
@@ -782,9 +769,8 @@
 	data->min    = policy->min;
 	data->max    = policy->max;
 
-	if (cpufreq_driver->setpolicy) {
-		data->policy = policy->policy;
-		ret = cpufreq_driver->setpolicy(policy);
+	if (cpufreq_driver->range) {
+		ret = cpufreq_driver->range(policy);
 	} else {
 		if (policy->governor != data->governor) {
 			/* save old, working values */
@@ -838,7 +824,6 @@
 	ret = __cpufreq_set_policy(data, policy);
 	data->user_policy.min = data->min;
 	data->user_policy.max = data->max;
-	data->user_policy.policy = data->policy;
 	data->user_policy.governor = data->governor;
 
 	up(&data->lock);
@@ -872,7 +857,6 @@
 	       sizeof(struct cpufreq_policy));
 	policy.min = data->user_policy.min;
 	policy.max = data->user_policy.max;
-	policy.policy = data->user_policy.policy;
 	policy.governor = data->user_policy.governor;
 
 	ret = __cpufreq_set_policy(data, &policy);
@@ -965,7 +949,7 @@
 	unsigned long flags;
 
 	if (!driver_data || !driver_data->verify || !driver_data->init ||
-	    ((!driver_data->setpolicy) && (!driver_data->target)))
+	    ((!driver_data->range) && (!driver_data->target)))
 		return -EINVAL;
 
 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
diff -ruN linux-original/drivers/cpufreq/proc_intf.c linux/drivers/cpufreq/proc_intf.c
--- linux-original/drivers/cpufreq/proc_intf.c	2003-11-04 15:27:37.000000000 +0100
+++ linux/drivers/cpufreq/proc_intf.c	2003-11-04 22:22:57.206522072 +0100
@@ -39,7 +39,6 @@
 
 	policy->min = 0;
 	policy->max = 0;
-	policy->policy = 0;
 	policy->cpu = CPUFREQ_ALL_CPUS;
 
 	if (sscanf(input_string, "%d:%d:%d:%15s", &cpu, &min, &max, str_governor) == 4) 
@@ -82,7 +81,7 @@
 	return -EINVAL;
 
 scan_policy:
-	result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
+	result = cpufreq_parse_governor(str_governor, &policy->governor);
 
 	return result;
 }
@@ -126,19 +125,7 @@
 
 		p += sprintf(p, "CPU%3d    %9d kHz (%3d %%)  -  %9d kHz (%3d %%)  -  ",
 			     i , policy.min, min_pctg, policy.max, max_pctg);
-		if (policy.policy) {
-			switch (policy.policy) {
-				case CPUFREQ_POLICY_POWERSAVE:
-				p += sprintf(p, "powersave\n");
-				break;	
-			case CPUFREQ_POLICY_PERFORMANCE:
-				p += sprintf(p, "performance\n");
-				break;
-			default:
-				p += sprintf(p, "INVALID\n");
-				break;
-			} 
-		} else
+		if (policy.governor)
 			p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
 	}
 end:
diff -ruN linux-original/include/linux/cpufreq.h linux/include/linux/cpufreq.h
--- linux-original/include/linux/cpufreq.h	2003-11-04 17:02:06.000000000 +0100
+++ linux/include/linux/cpufreq.h	2003-11-04 22:19:11.908772536 +0100
@@ -37,12 +37,7 @@
 
 
 /* if (cpufreq_driver->target) exists, the ->governor decides what frequency
- * within the limits is used. If (cpufreq_driver->setpolicy> exists, these
- * two generic policies are available:
- */
-
-#define CPUFREQ_POLICY_POWERSAVE	(1)
-#define CPUFREQ_POLICY_PERFORMANCE	(2)
+ * within the limits is used.  */
 
 /* Frequency values here are CPU kHz so that hardware which doesn't run 
  * with some frequencies can complain without having to guess what per 
@@ -63,7 +58,6 @@
 struct cpufreq_real_policy {
 	unsigned int		min;    /* in kHz */
 	unsigned int		max;    /* in kHz */
-        unsigned int		policy; /* see above */
 	struct cpufreq_governor	*governor; /* see below */
 };
 
@@ -73,12 +67,12 @@
 
 	unsigned int		min;    /* in kHz */
 	unsigned int		max;    /* in kHz */
-	unsigned int		cur;    /* in kHz, only needed if cpufreq
-					 * governors are used */
-        unsigned int		policy; /* see above */
+
+	/* the following two entries are only valid if ->target is used */
+	unsigned int		cur;    /* in kHz */
 	struct cpufreq_governor	*governor; /* see below */
 
- 	struct semaphore	lock;   /* CPU ->setpolicy or ->target may
+ 	struct semaphore	lock;   /* CPU ->range or ->target may
 					   only be called once a time */
 
 	struct cpufreq_real_policy	user_policy;
@@ -181,7 +175,7 @@
 	int	(*verify)	(struct cpufreq_policy *policy);
 
 	/* define one out of two */
-	int	(*setpolicy)	(struct cpufreq_policy *policy);
+	int	(*range)	(struct cpufreq_policy *policy);
 	int	(*target)	(struct cpufreq_policy *policy,
 				 unsigned int target_freq,
 				 unsigned int relation);
@@ -229,7 +223,7 @@
 int cpufreq_update_policy(unsigned int cpu);
 
 /* the proc_intf.c needs this */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
+int cpufreq_parse_governor (char *str_governor, struct cpufreq_governor **governor);
 
 #if defined(CONFIG_CPU_FREQ_GOV_USERSPACE) || defined(CONFIG_CPU_FREQ_GOV_USERSPACE_MODULE)
 /*********************************************************************

[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Cpufreq mailing list
Cpufreq@www.linux.org.uk
http://www.linux.org.uk/mailman/listinfo/cpufreq

                 reply	other threads:[~2003-11-04 21:30 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20031104213015.GA7175@brodo.de \
    --to=linux@brodo.de \
    --cc=cpufreq@www.linux.org.uk \
    --cc=davej@codemonkey.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox