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

 

参考文献

[1] http://www.builder.com.cn/2008/0326/784106.shtml

posted @ 2012-06-01 17:13  sky-zhang  阅读(3705)  评论(0编辑  收藏  举报