cpufreq cmdline handling c/s 19147 adjust cpufreq cmdline handling, this patch is a complement to c/s 19147. In this patch, 1. add common para (governor independent para) handling; 2. change governor dependent para handling method, governor dependent para will only be handled by the handler of that governor (not by all governors); 3. add userspace governor dependent para handling; 4. change para name 'threshold' of ondemand governor to 'up_threshold' since ondemand has only 'up_threshold', and conservative governor (will be implemented later) has both 'up_threshold' and 'down_threshold'; 5. change some coding style (c/s 19147, drivers/cpufreq/cpufreq.c) to keep coordination with original drivers/cpufreq/cpufreq.c coding style; (originally this file is ported from linux, we partly use linux coding style) Signed-off-by: Liu, Jinsong diff -r de853e901b5c xen/drivers/cpufreq/cpufreq.c --- a/xen/drivers/cpufreq/cpufreq.c Wed Feb 04 15:29:51 2009 +0000 +++ b/xen/drivers/cpufreq/cpufreq.c Sun Feb 08 13:07:45 2009 +0800 @@ -45,6 +45,9 @@ #include #include #include + +static unsigned int usr_max_freq, usr_min_freq; +static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy); struct cpufreq_dom { unsigned int dom; @@ -214,6 +217,9 @@ int cpufreq_add_cpu(unsigned int cpu) perf->domain_info.num_processors) { memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); policy->governor = NULL; + + cpufreq_cmdline_common_para(&new_policy); + ret = __cpufreq_set_policy(policy, &new_policy); if (ret) { if (new_policy.governor == CPUFREQ_DEFAULT_GOVERNOR) @@ -468,47 +474,71 @@ out: return ret; } +static void cpufreq_cmdline_common_para(struct cpufreq_policy *new_policy) +{ + if (usr_max_freq) + new_policy->max = usr_max_freq; + if (usr_min_freq) + new_policy->min = usr_min_freq; +} + +static int __init cpufreq_handle_common_option(const char *name, const char *val) +{ + if (!strcmp(name, "maxfreq") && val) { + usr_max_freq = simple_strtoul(val, NULL, 0); + return 1; + } + + if (!strcmp(name, "minfreq") && val) { + usr_min_freq = simple_strtoul(val, NULL, 0); + return 1; + } + + return 0; +} + void __init cpufreq_cmdline_parse(char *str) { static struct cpufreq_governor *__initdata cpufreq_governors[] = { + #define CPUFREQ_DEFAULT_GOVERNOR_INDEX 0; &cpufreq_gov_userspace, &cpufreq_gov_dbs, &cpufreq_gov_performance, &cpufreq_gov_powersave }; + unsigned int gov_index = CPUFREQ_DEFAULT_GOVERNOR_INDEX; do { char *val, *end = strchr(str, ','); unsigned int i; - if ( end ) + if (end) *end++ = '\0'; val = strchr(str, '='); - if ( val ) + if (val) *val++ = '\0'; - if ( !cpufreq_opt_governor ) - { - if ( !val ) - { - for ( i = 0; i < ARRAY_SIZE(cpufreq_governors); ++i ) - if ( !strcmp(str, cpufreq_governors[i]->name) ) - { + if (!cpufreq_opt_governor) { + if (!val) + for (i = 0; i < ARRAY_SIZE(cpufreq_governors); ++i) + if (!strcmp(str, cpufreq_governors[i]->name)) { cpufreq_opt_governor = cpufreq_governors[i]; + gov_index = i; str = NULL; break; } - } else cpufreq_opt_governor = CPUFREQ_DEFAULT_GOVERNOR; } - if ( str ) - for ( i = 0; i < ARRAY_SIZE(cpufreq_governors); ++i ) - if ( cpufreq_governors[i]->handle_option ) - cpufreq_governors[i]->handle_option(str, val); + if (str) { + if (cpufreq_handle_common_option(str, val)) + ; + else if (cpufreq_governors[gov_index]->handle_option) + cpufreq_governors[gov_index]->handle_option(str, val); + } str = end; - } while ( str ); + } while (str); } diff -r de853e901b5c xen/drivers/cpufreq/cpufreq_misc_governors.c --- a/xen/drivers/cpufreq/cpufreq_misc_governors.c Wed Feb 04 15:29:51 2009 +0000 +++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c Sun Feb 08 13:07:45 2009 +0800 @@ -18,6 +18,7 @@ #include #include +static unsigned int usr_speed; /* * cpufreq userspace governor @@ -26,6 +27,7 @@ static int cpufreq_governor_userspace(st unsigned int event) { int ret = 0; + unsigned int freq; if (!policy) return -EINVAL; @@ -35,12 +37,17 @@ static int cpufreq_governor_userspace(st case CPUFREQ_GOV_STOP: break; case CPUFREQ_GOV_LIMITS: - if (policy->max < policy->cur) + freq = usr_speed ? : policy->cur; + if (policy->max < freq) ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - else if (policy->min > policy->cur) + else if (policy->min > freq) ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); + else if (usr_speed) + ret = __cpufreq_driver_target(policy, freq, + CPUFREQ_RELATION_L); + break; default: ret = -EINVAL; @@ -50,9 +57,17 @@ static int cpufreq_governor_userspace(st return ret; } +static void __init +cpufreq_userspace_handle_option(const char *name, const char *val) +{ + if (!strcmp(name, "speed") && val) + usr_speed = simple_strtoul(val, NULL, 0); +} + struct cpufreq_governor cpufreq_gov_userspace = { .name = "userspace", .governor = cpufreq_governor_userspace, + .handle_option = cpufreq_userspace_handle_option }; static int __init cpufreq_gov_userspace_init(void) diff -r de853e901b5c xen/drivers/cpufreq/cpufreq_ondemand.c --- a/xen/drivers/cpufreq/cpufreq_ondemand.c Wed Feb 04 15:29:51 2009 +0000 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Sun Feb 08 13:07:45 2009 +0800 @@ -287,7 +287,7 @@ static void __init cpufreq_dbs_handle_op { usr_sampling_rate = simple_strtoull(val, NULL, 0) * MICROSECS(1); } - else if ( !strcmp(name, "threshold") && val ) + else if ( !strcmp(name, "up_threshold") && val ) { unsigned long tmp = simple_strtoul(val, NULL, 0);