diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 613314851ecc..64926aa990db 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -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, "\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 }; diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index f8cdde4bf6cd..cb2ac01a41a1 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/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); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 23932d7741a9..ddd8652fc3f3 100644 --- a/include/linux/cpufreq.h +++ b/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 */