cpufreq: frequency table helpers
PATCH 1/1 cpufreq: frequency table helpers
This patch adds "frequency table helpers" to kernel/cpufreq.c and updates some drivers to use them.
Most CPU frequency scaling methods only support a few static frequencies. In these drivers a lot of duplicated code existed in the ->setpolicy and ->verify calls.
Please note that this in no way changes the behaviour of cpufreq or of the ->setpolicy or ->verify calls. These "frequency table helpers" aren't for drivers which either only support policies (longrun) or really many frequency states (ARM, gx-suspmod).
Dominik
arch/i386/kernel/cpu/cpufreq/elanfreq.c | 83 ++++++------------- arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 97 +++++++---------------- arch/i386/kernel/cpu/cpufreq/powernow-k6.c | 122 ++++++++--------------------- arch/i386/kernel/cpu/cpufreq/speedstep.c | 57 +++++-------- include/linux/cpufreq.h | 23 +++++ kernel/cpufreq.c | 117 +++++++++++++++++++++++++++ 6 files changed, 257 insertions(+), 242 deletions(-)
arch/i386/kernel/cpu/cpufreq/elanfreq.c +28 -55
@@ -61,6 +61,18 @@ {99000, 0x01, 0x05} }; +static struct cpufreq_frequency_table elanfreq_table[] = { + {0 ,1000 }, + {1 ,2000 }, + {2 ,4000 }, + {3 ,8000 }, + {4 ,16000 }, + {5 ,33000 }, + {6 ,66000 }, + {7 ,99000 }, + {0 ,CPUFREQ_TABLE_END }, +}; +/** * elanfreq_get_cpu_frequency: determine current cpu speed
@@ -172,63 +184,17 @@static int elanfreq_verify (struct cpufreq_policy *policy) { -unsigned int number_states =0 ; -unsigned int i; - -if (!policy || !max_freq) -return -EINVAL ; - - policy->cpu =0 ; - -cpufreq_verify_within_limits (policy,1000 , max_freq); - -for (i=7 ; i>=0 ; i--) -if ((elan_multiplier[i].clock >= policy->min) && - (elan_multiplier[i].clock <= policy->max)) - number_states++; - -if (number_states) -return 0 ; - -for (i=7 ; i>=0 ; i--) -if (elan_multiplier[i].clock < policy->max) -break ; - - policy->max = elan_multiplier[i+1 ].clock; - -cpufreq_verify_within_limits (policy,1000 , max_freq); - -return 0 ; +return cpufreq_frequency_table_verify (policy, &elanfreq_table[0 ]); }static int elanfreq_setpolicy (struct cpufreq_policy *policy) { -unsigned int i; -unsigned int optimal =8 ; - -if (!elanfreq_driver) -return -EINVAL ; +unsigned int newstate =0 ; -for (i=0 ; i<8 ; i++) { -if ((elan_multiplier[i].clock > policy->max) || - (elan_multiplier[i].clock < policy->min)) -continue ; -switch (policy->policy) { -case CPUFREQ_POLICY_POWERSAVE : -if (optimal ==8 ) - optimal = i; -break ; -case CPUFREQ_POLICY_PERFORMANCE : - optimal = i; -break ; -default : -return -EINVAL ; - } - } -if ((optimal ==8 ) || (elan_multiplier[optimal].clock > max_freq)) +if (cpufreq_frequency_table_setpolicy (policy, &elanfreq_table[0 ], &newstate))return -EINVAL ; -elanfreq_set_cpu_state (optimal); +elanfreq_set_cpu_state (newstate);return 0 ; }
@@ -262,7 +228,7 @@ {struct cpuinfo_x86 *c = cpu_data;struct cpufreq_driver *driver; -int ret; +int ret, i;/* Test if we have the right hardware */ if ((c->x86_vendor != X86_VENDOR_AMD) ||
@@ -282,6 +248,12 @@if (!max_freq) max_freq =elanfreq_get_cpu_frequency (); +/* table init */ +for (i=0 ; (elanfreq_table[i].frequency !=CPUFREQ_TABLE_END ); i++) { +if (elanfreq_table[i].frequency > max_freq) + elanfreq_table[i].frequency =CPUFREQ_ENTRY_INVALID ; + } +#ifdef CONFIG_CPU_FREQ_24_API driver->cpu_cur_freq[0 ] =elanfreq_get_cpu_frequency ();#endif
@@ -290,11 +262,12 @@ driver->setpolicy = &elanfreq_setpolicy; driver->policy[0 ].cpu =0 ; - driver->policy[0 ].min =1000 ; - driver->policy[0 ].max = max_freq; + ret =cpufreq_frequency_table_cpuinfo (&driver->policy[0 ], &elanfreq_table[0 ]); +if (ret) { +kfree (driver); +return ret; + } driver->policy[0 ].policy =CPUFREQ_POLICY_PERFORMANCE ; - driver->policy[0 ].cpuinfo.max_freq = max_freq; - driver->policy[0 ].cpuinfo.min_freq =1000 ; driver->policy[0 ].cpuinfo.transition_latency =CPUFREQ_ETERNAL ; elanfreq_driver = driver;
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +32 -65
128 lines not on this page · raw message
arch/i386/kernel/cpu/cpufreq/powernow-k6.c +35 -87
179 lines not on this page · raw message
arch/i386/kernel/cpu/cpufreq/speedstep.c +22 -35
92 lines not on this page · raw message
include/linux/cpufreq.h +23 -0
@@ -241,4 +241,27 @@#endif /* CONFIG_CPU_FREQ_24_API */ +/********************************************************************* +* FREQUENCY TABLE HELPERS * +*********************************************************************/ + +#define CPUFREQ_ENTRY_INVALID ~0 +#define CPUFREQ_TABLE_END ~1 + +struct cpufreq_frequency_table { +unsigned int index;/* any */ +unsigned int frequency;/* kHz - doesn't need to be in ascending +* order */ +}; + +int cpufreq_frequency_table_cpuinfo (struct cpufreq_policy *policy, +struct cpufreq_frequency_table *table); + +int cpufreq_frequency_table_verify (struct cpufreq_policy *policy, +struct cpufreq_frequency_table *table); + +int cpufreq_frequency_table_setpolicy (struct cpufreq_policy *policy, +struct cpufreq_frequency_table *table, +unsigned int *index); +#endif /* _LINUX_CPUFREQ_H */
kernel/cpufreq.c +117 -0
120 lines not on this page · raw message