Commit 8251e580 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] cpufreq: move /proc/cpufreq interface code to extra module

The deprecated /proc/cpufreq interface can easily live outside the
cpufreq core now.
parent 589e8be9
......@@ -539,8 +539,8 @@ config CPU_FREQ_24_API
depends on CPU_FREQ
default y
config CPU_FREQ_26_API
bool
config CPU_FREQ_PROC_INTF
tristate
depends on CPU_FREQ
default y
......
......@@ -969,7 +969,7 @@ config CPU_FREQ
If in doubt, say N.
config CPU_FREQ_PROC_INTF
bool "/proc/cpufreq interface (DEPRECATED)"
tristate "/proc/cpufreq interface (DEPRECATED)"
depends on CPU_FREQ && PROC_FS
help
This enables the /proc/cpufreq interface for controlling
......
......@@ -151,7 +151,7 @@ config CPU_FREQ
If in doubt, say N.
config CPU_FREQ_PROC_INTF
bool "/proc/cpufreq interface (DEPRECATED)"
tristate "/proc/cpufreq interface (DEPRECATED)"
depends on CPU_FREQ && PROC_FS
help
This enables the /proc/cpufreq interface for controlling
......
config CPU_FREQ_PROC_INTF
tristate "/proc/cpufreq interface (deprecated)"
depends on CPU_FREQ && PROC_FS
help
This enables the /proc/cpufreq interface for controlling
CPUFreq. Please note that it is recommended to use the sysfs
interface instead (which is built automatically).
For details, take a look at linux/Documentation/cpufreq.
If in doubt, say N.
#CPUfreq governors and cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
obj-$(CONFIG_CPU_FREQ_PROC_INTF) += proc_intf.o
/*
* linux/drivers/cpufreq/proc_intf.c
*
* Copyright (C) 2002 - 2003 Dominik Brodowski
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/ctype.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
/**
* cpufreq_parse_policy - parse a policy string
* @input_string: the string to parse.
* @policy: the policy written inside input_string
*
* This function parses a "policy string" - something the user echo'es into
* /proc/cpufreq or gives as boot parameter - into a struct cpufreq_policy.
* If there are invalid/missing entries, they are replaced with current
* cpufreq policy.
*/
static int cpufreq_parse_policy(char input_string[42], struct cpufreq_policy *policy)
{
unsigned int min = 0;
unsigned int max = 0;
unsigned int cpu = 0;
char str_governor[16];
struct cpufreq_policy current_policy;
unsigned int result = -EFAULT;
if (!policy)
return -EINVAL;
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)
{
policy->min = min;
policy->max = max;
policy->cpu = cpu;
result = 0;
goto scan_policy;
}
if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
{
if (!cpufreq_get_policy(&current_policy, cpu)) {
policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
policy->cpu = cpu;
result = 0;
goto scan_policy;
}
}
if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3)
{
policy->min = min;
policy->max = max;
result = 0;
goto scan_policy;
}
if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
{
if (!cpufreq_get_policy(&current_policy, cpu)) {
policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
result = 0;
goto scan_policy;
}
}
return -EINVAL;
scan_policy:
result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
return result;
}
/**
* cpufreq_proc_read - read /proc/cpufreq
*
* This function prints out the current cpufreq policy.
*/
static int cpufreq_proc_read (
char *page,
char **start,
off_t off,
int count,
int *eof,
void *data)
{
char *p = page;
int len = 0;
struct cpufreq_policy policy;
unsigned int min_pctg = 0;
unsigned int max_pctg = 0;
unsigned int i = 0;
if (off != 0)
goto end;
p += sprintf(p, " minimum CPU frequency - maximum CPU frequency - policy\n");
for (i=0;i<NR_CPUS;i++) {
if (!cpu_online(i))
continue;
if (cpufreq_get_policy(&policy, i))
continue;
if (!policy.cpuinfo.max_freq)
continue;
min_pctg = (policy.min * 100) / policy.cpuinfo.max_freq;
max_pctg = (policy.max * 100) / policy.cpuinfo.max_freq;
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:
p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
break;
default:
p += sprintf(p, "INVALID\n");
break;
}
}
end:
len = (p - page);
if (len <= off+count)
*eof = 1;
*start = page + off;
len -= off;
if (len>count)
len = count;
if (len<0)
len = 0;
return len;
}
/**
* cpufreq_proc_write - handles writing into /proc/cpufreq
*
* This function calls the parsing script and then sets the policy
* accordingly.
*/
static int cpufreq_proc_write (
struct file *file,
const char *buffer,
unsigned long count,
void *data)
{
int result = 0;
char proc_string[42] = {'\0'};
struct cpufreq_policy policy;
unsigned int i = 0;
if ((count > sizeof(proc_string) - 1))
return -EINVAL;
if (copy_from_user(proc_string, buffer, count))
return -EFAULT;
proc_string[count] = '\0';
result = cpufreq_parse_policy(proc_string, &policy);
if (result)
return -EFAULT;
if (policy.cpu == CPUFREQ_ALL_CPUS)
{
for (i=0; i<NR_CPUS; i++)
{
policy.cpu = i;
if (cpu_online(i))
cpufreq_set_policy(&policy);
}
}
else
cpufreq_set_policy(&policy);
return count;
}
/**
* cpufreq_proc_init - add "cpufreq" to the /proc root directory
*
* This function adds "cpufreq" to the /proc root directory.
*/
static int __init cpufreq_proc_init (void)
{
struct proc_dir_entry *entry = NULL;
/* are these acceptable values? */
entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR,
&proc_root);
if (!entry) {
printk(KERN_ERR "unable to create /proc/cpufreq entry\n");
return -EIO;
} else {
entry->read_proc = cpufreq_proc_read;
entry->write_proc = cpufreq_proc_write;
}
return 0;
}
/**
* cpufreq_proc_exit - removes "cpufreq" from the /proc root directory.
*
* This function removes "cpufreq" from the /proc root directory.
*/
static void __exit cpufreq_proc_exit (void)
{
remove_proc_entry("cpufreq", &proc_root);
return;
}
MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("CPUfreq /proc/cpufreq interface");
MODULE_LICENSE ("GPL");
module_init(cpufreq_proc_init);
module_exit(cpufreq_proc_exit);
......@@ -205,6 +205,8 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
int cpufreq_restore(void);
#endif
/* the proc_intf.c needs this */
int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
#ifdef CONFIG_CPU_FREQ_24_API
/*********************************************************************
......
......@@ -23,12 +23,6 @@
#include <linux/device.h>
#include <linux/slab.h>
#ifdef CONFIG_CPU_FREQ_PROC_INTF
#include <linux/ctype.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#endif
#ifdef CONFIG_CPU_FREQ_24_API
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
......@@ -77,7 +71,7 @@ static int cpufreq_governor(unsigned int cpu, unsigned int event);
/**
* cpufreq_parse_governor - parse a governor string
*/
static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor)
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;
......@@ -103,6 +97,7 @@ static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, str
}
return -EINVAL;
}
EXPORT_SYMBOL_GPL(cpufreq_parse_governor);
/* forward declarations */
......@@ -429,241 +424,6 @@ static int cpufreq_remove_dev (struct intf_data *intf)
}
/*********************************************************************
* /proc/cpufreq INTERFACE *
*********************************************************************/
#ifdef CONFIG_CPU_FREQ_PROC_INTF
/**
* cpufreq_parse_policy - parse a policy string
* @input_string: the string to parse.
* @policy: the policy written inside input_string
*
* This function parses a "policy string" - something the user echo'es into
* /proc/cpufreq or gives as boot parameter - into a struct cpufreq_policy.
* If there are invalid/missing entries, they are replaced with current
* cpufreq policy.
*/
static int cpufreq_parse_policy(char input_string[42], struct cpufreq_policy *policy)
{
unsigned int min = 0;
unsigned int max = 0;
unsigned int cpu = 0;
char str_governor[16];
struct cpufreq_policy current_policy;
unsigned int result = -EFAULT;
if (!policy)
return -EINVAL;
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)
{
policy->min = min;
policy->max = max;
policy->cpu = cpu;
result = 0;
goto scan_policy;
}
if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
{
if (!cpufreq_get_policy(&current_policy, cpu)) {
policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
policy->cpu = cpu;
result = 0;
goto scan_policy;
}
}
if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3)
{
policy->min = min;
policy->max = max;
result = 0;
goto scan_policy;
}
if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
{
if (!cpufreq_get_policy(&current_policy, cpu)) {
policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
result = 0;
goto scan_policy;
}
}
return -EINVAL;
scan_policy:
result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
return result;
}
/**
* cpufreq_proc_read - read /proc/cpufreq
*
* This function prints out the current cpufreq policy.
*/
static int cpufreq_proc_read (
char *page,
char **start,
off_t off,
int count,
int *eof,
void *data)
{
char *p = page;
int len = 0;
struct cpufreq_policy policy;
unsigned int min_pctg = 0;
unsigned int max_pctg = 0;
unsigned int i = 0;
if (off != 0)
goto end;
p += sprintf(p, " minimum CPU frequency - maximum CPU frequency - policy\n");
for (i=0;i<NR_CPUS;i++) {
if (!cpu_online(i))
continue;
if (cpufreq_get_policy(&policy, i))
continue;
if (!policy.cpuinfo.max_freq)
continue;
min_pctg = (policy.min * 100) / policy.cpuinfo.max_freq;
max_pctg = (policy.max * 100) / policy.cpuinfo.max_freq;
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:
p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
break;
default:
p += sprintf(p, "INVALID\n");
break;
}
}
end:
len = (p - page);
if (len <= off+count)
*eof = 1;
*start = page + off;
len -= off;
if (len>count)
len = count;
if (len<0)
len = 0;
return len;
}
/**
* cpufreq_proc_write - handles writing into /proc/cpufreq
*
* This function calls the parsing script and then sets the policy
* accordingly.
*/
static int cpufreq_proc_write (
struct file *file,
const char *buffer,
unsigned long count,
void *data)
{
int result = 0;
char proc_string[42] = {'\0'};
struct cpufreq_policy policy;
unsigned int i = 0;
if ((count > sizeof(proc_string) - 1))
return -EINVAL;
if (copy_from_user(proc_string, buffer, count))
return -EFAULT;
proc_string[count] = '\0';
result = cpufreq_parse_policy(proc_string, &policy);
if (result)
return -EFAULT;
if (policy.cpu == CPUFREQ_ALL_CPUS)
{
for (i=0; i<NR_CPUS; i++)
{
policy.cpu = i;
if (cpu_online(i))
cpufreq_set_policy(&policy);
}
}
else
cpufreq_set_policy(&policy);
return count;
}
/**
* cpufreq_proc_init - add "cpufreq" to the /proc root directory
*
* This function adds "cpufreq" to the /proc root directory.
*/
static unsigned int cpufreq_proc_init (void)
{
struct proc_dir_entry *entry = NULL;
/* are these acceptable values? */
entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR,
&proc_root);
if (!entry) {
printk(KERN_ERR "unable to create /proc/cpufreq entry\n");
return -EIO;
} else {
entry->read_proc = cpufreq_proc_read;
entry->write_proc = cpufreq_proc_write;
}
return 0;
}
/**
* cpufreq_proc_exit - removes "cpufreq" from the /proc root directory.
*
* This function removes "cpufreq" from the /proc root directory.
*/
static void cpufreq_proc_exit (void)
{
remove_proc_entry("cpufreq", &proc_root);
return;
}
#else
#define cpufreq_proc_init() do {} while(0)
#define cpufreq_proc_exit() do {} while(0)
#endif /* CONFIG_CPU_FREQ_PROC_INTF */
/*********************************************************************
* /proc/sys/cpu/ INTERFACE *
*********************************************************************/
......@@ -1485,8 +1245,6 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
up(&cpufreq_driver_sem);
cpufreq_proc_init();
#ifdef CONFIG_CPU_FREQ_24_API
cpufreq_sysctl_init();
#endif
......@@ -1516,8 +1274,6 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
return -EINVAL;
}
cpufreq_proc_exit();
#ifdef CONFIG_CPU_FREQ_24_API
cpufreq_sysctl_exit();
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment