diff options
| author | Dave Jones <davej@redhat.com> | 2003-09-03 02:50:10 +0100 |
|---|---|---|
| committer | Dave Jones <davej@redhat.com> | 2003-09-03 02:50:10 +0100 |
| commit | e804252bee9e8c9463ff456f60e07f410eed1afb (patch) | |
| tree | 95f641af5cbabb50d10c1c9774d13298128ae716 | |
| parent | adff42b1c54cd001d28d4d0ad21127b9be6d4812 (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.c | 102 | ||||
| -rw-r--r-- | drivers/cpufreq/proc_intf.c | 26 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 21 |
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 * *********************************************************************/ |
