Linux cpufreq驱动框架
动态电源管理(DPM)是很一个广泛的概念,很多系统实际上都采用了动态电源管理(DPM)方式。Linux很早就采用了动态电源管理,在driver目录下有个cpufreq的驱动程序,它就是用来动态调整CPU频率以降低能源消耗的。[1] 注:引文中说的不全对,cpufreq在平板中有采用,并不是不适用与嵌入式系统。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
static struct cpufreq_frequency_table XXX_freq_table[] = {
{ 0, 66000 },
{ 0, 133000 },
{ 1, 222000 },
{ 1, 266000 },
{ 2, 333000 },
{ 2, 400000 },
{ 2, 532000 },
{ 2, 533000 },
{ 3, 667000 },
{ 0, CPUFREQ_TABLE_END },
};//此定义对应s3c64xx_freq_table
int XXX_cpufreq_verify_speed(struct cpufreq_policy *policy)
{
cpufreq_frequency_table_verify(policy,XXX_freq_table);
}
int XXX_cpufreq_init(struct cpufreq_policy *policy)
{
//检查XXX_freq_table的合法性或者根据配置生成XXX_freq_table,动态创建的话需要调用cpufreq_frequency_table_cpuinfo
//获取当前的频率赋给policy->cur
//初始化policy->cpuinfo.transition_latency
//调用cpufreq_frequency_table_get_attr
}
unsigned int XXX_getspeed(unsigned int cpu)
{
//获取当前的频率值
}
int XXX_target(struct cpufreq_policy *policy, unsigned target, unsigned relation)
{
//根据relation的值,重新计算合适的频率
switch (relation) {
case CPUFREQ_RELATION_L:
/* Try to select a new_freq higher than or equal target_freq */
dvfs_tbl = find_freq_ceil(target_freq);
break;
case CPUFREQ_RELATION_H:
/* Try to select a new_freq lower than or equal target_freq */
dvfs_tbl = find_freq_floor(target_freq);
break;
default:
dvfs_tbl = NULL;
break;
}
//重新调整频率【通知所有注册的notifier,并且调整时钟滴答jiffies】
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
//调整时钟锁相环的参数
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
struct cpufreq_driver XXX_cpufreq_driver
{
......
.verify = XXX_cpufreq_verify_speed;
.target = ;
.get = XXX_getspeed;
.init = XXX_cpufreq_init;
.exit = ;
.attr = ;
}
static int __init XXX_cpufreq_init( void )
{
cpufreq_register_driver(&XXX_cpufreq_driver);
}
module_init(XXX_cpufreq_init)
如果驱动需要响应cpu频率调整的消息,需要在驱动中调用如下函数注册notifier
cpufreq_register_notifier
参考文献