cpufreq的初始化讲解
cpufreq初始化
cpufreq的初始化,通过调用cpufreq_register_driver
接口,完成一系列的policy、governor和driver配置。
驱动module init入口
- driver编写module_init的函数,在初始化中使用
cpufreq_register_driver
注册驱动 cpufreq_register_driver
中会完成增加总线设备、节点创建等操作- 注册cpuhotplug的相关回调
stateDiagram
module_init --> xx_driver_init :在kernel初始化阶段调用driver的init函数
note left of xx_driver_init
为每个cpu定义了policy指针:static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
kernel只能有一个drvier:static struct cpufreq_driver *cpufreq_driver;
end note
xx_driver_init --> cpufreq_register_driver :在driver中调用cpufreq_register_driver,注册成功后,其他drvier会返回失败
cpufreq_register_driver --> subsys_interface_register: 在/sys/devices/system/cpu/cpuX/创建cpufreq节点
subsys_interface_register --> cpufreq_add_dev
cpufreq_add_dev --> cpufreq_online(cpu) :1
cpufreq_add_dev --> add_cpu_dev_symlink :2
note left of add_cpu_dev_symlink
软链接/sys/devices/system/cpu/cpuX/cpufreq
-> sys/devices/system/cpu/cpufreq/policyX
end note
第二部分
- 每个cpu走到cpufreq_online函数,会有两条路径
- 第一条是,如果它的policy已经被赋值,那么再检查下其governor是否已经start
- 第二条是,如果它的policy还是空,那么走driver的init回调,来初始化cpu对应的policy-cpus值和flag
- 根据返回的policy-cpus的值,去初始化其他cpu的policy
- 完成policy初始化,min、max
stateDiagram
cpufreq_online --> cpufreq_add_policy_cpu :cpufreq_cpu_data != NULL
cpufreq_online --> cpufreq_policy_alloc :cpufreq_cpu_data == NULL
note left of cpufreq_policy_alloc
在/sys/devices/system/cpu/cpufreq/创建policyX节点
end note
cpufreq_add_policy_cpu --> cpufreq_start_governor : policy->cpus为0,需要start governor,不是init
cpufreq_add_policy_cpu --> return : policy->cpus不为0,返回
cpufreq_policy_alloc --> cpufreq_driver_init(policy)
note right of cpufreq_driver_init(policy)
driver init主要完成clk和regulator等资源的初始化,
以及policy的初始化,
end note
cpufreq_driver_init(policy) --> for_each_cpu(policy) :再使用上面的policy->cpus对其他的cpu做初始化
for_each_cpu(policy) --> cpufreq_init_policy
Ref
https://www.kernel.org/doc/Documentation/cpu-freq/cpu-drivers.rst