summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Jones <davej@redhat.com>2003-09-03 02:50:10 +0100
committerDave Jones <davej@redhat.com>2003-09-03 02:50:10 +0100
commite804252bee9e8c9463ff456f60e07f410eed1afb (patch)
tree95f641af5cbabb50d10c1c9774d13298128ae716
parentadff42b1c54cd001d28d4d0ad21127b9be6d4812 (diff)
[CPUFREQ] Completely separate governors from policies.
Governors are for CPUfreq drivers which have a ->target callback, Policies are for CPUfreq drivers which have a ->setpolicy callback. Also, the "hardwired" governors "powersave" and "performance" are removed.
-rw-r--r--drivers/cpufreq/cpufreq.c102
-rw-r--r--drivers/cpufreq/proc_intf.c26
-rw-r--r--include/linux/cpufreq.h21
3 files changed, 74 insertions, 75 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 7f80c321c785..1b037bf0f950 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -109,13 +109,18 @@ static void cpufreq_cpu_put(struct cpufreq_policy *data)
int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
struct cpufreq_governor **governor)
{
- 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;
- return 0;
- } else {
+ 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;
+ return 0;
+ }
+ return -EINVAL;
+ } else {
struct cpufreq_governor *t;
down(&cpufreq_governor_sem);
if (!cpufreq_driver || !cpufreq_driver->target)
@@ -123,7 +128,6 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
*governor = t;
- *policy = CPUFREQ_POLICY_GOVERNOR;
up(&cpufreq_governor_sem);
return 0;
}
@@ -190,16 +194,13 @@ store_one(scaling_max_freq,max);
*/
static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf)
{
- switch (policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
+ if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
return sprintf(buf, "powersave\n");
- case CPUFREQ_POLICY_PERFORMANCE:
+ else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
return sprintf(buf, "performance\n");
- case CPUFREQ_POLICY_GOVERNOR:
+ else if (policy->governor)
return snprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
- default:
- return -EINVAL;
- }
+ return -EINVAL;
}
@@ -246,15 +247,15 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
ssize_t i = 0;
struct cpufreq_governor *t;
- i += sprintf(buf, "performance powersave");
-
- if (!cpufreq_driver->target)
+ 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;
- i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name);
+ i += snprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
}
out:
i += sprintf(&buf[i], "\n");
@@ -396,10 +397,12 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_cpu_data[cpu] = policy;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
+ policy->governor = NULL; /* to assure that the starting sequence is
+ * run in cpufreq_set_policy */
up(&policy->lock);
/* set default policy */
+
ret = cpufreq_set_policy(&new_policy);
if (ret)
goto err_out_unregister;
@@ -622,33 +625,18 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target);
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
{
- int ret = 0;
+ int ret = -EINVAL;
- switch (policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) {
- ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
- }
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) {
- ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
- }
- break;
- case CPUFREQ_POLICY_GOVERNOR:
- ret = -EINVAL;
- if (!try_module_get(policy->governor->owner))
- break;
- ret = policy->governor->governor(policy, event);
- /* we keep one module reference alive for each CPU governed by this CPU */
- if ((event != CPUFREQ_GOV_START) || ret)
- module_put(policy->governor->owner);
- if ((event == CPUFREQ_GOV_STOP) && !ret)
- module_put(policy->governor->owner);
- break;
- default:
- ret = -EINVAL;
- }
+ if (!try_module_get(policy->governor->owner))
+ return -EINVAL;
+
+ ret = policy->governor->governor(policy, event);
+
+ /* we keep one module reference alive for each CPU governed by this CPU */
+ if ((event != CPUFREQ_GOV_START) || ret)
+ module_put(policy->governor->owner);
+ if ((event == CPUFREQ_GOV_STOP) && !ret)
+ module_put(policy->governor->owner);
return ret;
}
@@ -680,11 +668,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
if (!governor)
return -EINVAL;
- if (!strnicmp(governor->name,"powersave",CPUFREQ_NAME_LEN))
- return -EBUSY;
- if (!strnicmp(governor->name,"performance",CPUFREQ_NAME_LEN))
- return -EBUSY;
-
down(&cpufreq_governor_sem);
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
@@ -808,23 +791,24 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
data->policy = policy->policy;
ret = cpufreq_driver->setpolicy(policy);
} else {
- if ((policy->policy != data->policy) ||
- ((policy->policy == CPUFREQ_POLICY_GOVERNOR) && (policy->governor != data->governor))) {
+ if (policy->governor != data->governor) {
/* save old, working values */
- unsigned int old_pol = data->policy;
struct cpufreq_governor *old_gov = data->governor;
/* end old governor */
- __cpufreq_governor(data, CPUFREQ_GOV_STOP);
+ if (data->governor)
+ __cpufreq_governor(data, CPUFREQ_GOV_STOP);
/* start new governor */
- data->policy = policy->policy;
data->governor = policy->governor;
if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
/* new governor failed, so re-start old one */
- data->policy = old_pol;
- data->governor = old_gov;
- __cpufreq_governor(data, CPUFREQ_GOV_START);
+ if (old_gov) {
+ data->governor = old_gov;
+ __cpufreq_governor(data, CPUFREQ_GOV_START);
+ }
+ ret = -EINVAL;
+ goto error_out;
}
/* might be a policy change, too, so fall through */
}
diff --git a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c
index d314e526af9c..b8d6b056051a 100644
--- a/drivers/cpufreq/proc_intf.c
+++ b/drivers/cpufreq/proc_intf.c
@@ -126,20 +126,20 @@ static int cpufreq_proc_read (
p += sprintf(p, "CPU%3d %9d kHz (%3d %%) - %9d kHz (%3d %%) - ",
i , policy.min, min_pctg, policy.max, max_pctg);
- switch (policy.policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- p += sprintf(p, "powersave\n");
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- p += sprintf(p, "performance\n");
- break;
- case CPUFREQ_POLICY_GOVERNOR:
+ 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
p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
- break;
- default:
- p += sprintf(p, "INVALID\n");
- break;
- }
}
end:
len = (p - page);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3d466f6680cb..f920b0a8e83e 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -36,11 +36,13 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
#define CPUFREQ_POLICY_NOTIFIER (1)
-/********************** cpufreq policy notifiers *********************/
+/* 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)
-#define CPUFREQ_POLICY_GOVERNOR (3)
/* Frequency values here are CPU kHz so that hardware which doesn't run
* with some frequencies can complain without having to guess what per
@@ -151,6 +153,7 @@ int cpufreq_governor(unsigned int cpu, unsigned int event);
int cpufreq_register_governor(struct cpufreq_governor *governor);
void cpufreq_unregister_governor(struct cpufreq_governor *governor);
+
/*********************************************************************
* CPUFREQ DRIVER INTERFACE *
*********************************************************************/
@@ -221,7 +224,6 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpu
/*********************************************************************
* CPUFREQ USERSPACE GOVERNOR *
*********************************************************************/
-extern struct cpufreq_governor cpufreq_gov_userspace;
int cpufreq_gov_userspace_init(void);
int cpufreq_setmax(unsigned int cpu);
@@ -280,6 +282,19 @@ enum {
/*********************************************************************
+ * CPUFREQ DEFAULT GOVERNOR *
+ *********************************************************************/
+
+
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+extern struct cpufreq_governor cpufreq_gov_performance;
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance
+#elif CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
+extern struct cpufreq_governor cpufreq_gov_userspace;
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
+#endif
+
+/*********************************************************************
* FREQUENCY TABLE HELPERS *
*********************************************************************/