/* * linux/drivers/cpufreq/proc_intf.c * * Copyright (C) 2002 - 2003 Dominik Brodowski */ #include #include #include #include #include #include #include #define CPUFREQ_ALL_CPUS ((NR_CPUS)) /** * 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(¤t_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(¤t_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;iname); } 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 __user *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; iread_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 "); MODULE_DESCRIPTION ("CPUfreq /proc/cpufreq interface"); MODULE_LICENSE ("GPL"); module_init(cpufreq_proc_init); module_exit(cpufreq_proc_exit);