cpufreq 代码分析
基础知识:
cpufreq 代码分析
从 drivers\cpufreq\Makefile 开始,(注:我的是linux-4.14.63)
# SPDX-License-Identifier: GPL-2.0
# CPUfreq core
obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o # cpufreq core 代码
# CPUfreq stats
obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o # cpufreq stats
# CPUfreq governors
obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o # 对应于cpufreq 五种模式
obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o
obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o
obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o # cpufreq_driver dt 表示设备树版
obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o
//....
驱动入口:
cpufreq-dt.c:
static struct platform_driver dt_cpufreq_platdrv = {
.driver = {
.name = "cpufreq-dt",
},
.probe = dt_cpufreq_probe,
.remove = dt_cpufreq_remove,
};
module_platform_driver(dt_cpufreq_platdrv);
可以看出这是个平台驱动,与之对应的平台设备的添加在cpufreq-dt-platdev.c:
static int __init cpufreq_dt_platdev_init(void)
{
create_pdev:
of_node_put(np);
return PTR_ERR_OR_ZERO(platform_device_register_data(NULL, "cpufreq-dt",
-1, data,
sizeof(struct cpufreq_dt_platform_data)));
}
device_initcall(cpufreq_dt_platdev_init);
device_initcall(cpufreq_dt_platdev_init); 表示该函数在内核启动过程中会被调用。
继续看 probe 函数,dt_cpufreq_probe:
ret = cpufreq_register_driver(&dt_cpufreq_driver);
dt_cpufreq_driver 的定义
static struct cpufreq_driver dt_cpufreq_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify,
.target_index = set_target,
.get = cpufreq_generic_get,
.init = cpufreq_init,
.exit = cpufreq_exit,
.ready = cpufreq_ready,
.name = "cpufreq-dt",
.attr = cpufreq_dt_attr,
.suspend = cpufreq_generic_suspend,c
};
继续跟踪 cpufreq_register_driver
int cpufreq_register_driver(struct cpufreq_driver *driver_data)
{
cpufreq_driver = driver_data; // 1.给 cpufreq_driver 赋值
ret = subsys_interface_register(&cpufreq_interface); // 2.注册 cpufreq_interface
// ...
}
cpufreq_interface 的定义
static struct subsys_interface cpufreq_interface = {
.name = "cpufreq",
.subsys = &cpu_subsys,
.add_dev = cpufreq_add_dev,
.remove_dev = cpu

1135

被折叠的 条评论
为什么被折叠?



