驱动的加载过程
(1) camsys driver入口函数
根据 ./kernel/drivers/media/video/rk_camsys 目录下的Makefile可以了解到,该目录源码最终会生成camsys_drv.o模块,设备端加载camsys_drv.o这个模块时,会调用这个模块中module_init注册的入口函数camsys_platform_init,具体代码如下:
module_init(camsys_platform_init);
static int __init camsys_platform_init(void)
{
printk("CamSys driver version: v%d.%d.%d, "
"CamSys head file version: v%d.%d.%d\n",
(CAMSYS_DRIVER_VERSION&0xff0000) >> 16,
(CAMSYS_DRIVER_VERSION&0xff00) >> 8,
CAMSYS_DRIVER_VERSION&0xff,
(CAMSYS_HEAD_VERSION&0xff0000) >> 16,
(CAMSYS_HEAD_VERSION&0xff00) >> 8,
CAMSYS_HEAD_VERSION&0xff);
spin_lock_init(&camsys_devs.lock);
INIT_LIST_HEAD(&camsys_devs.devs);
platform_driver_register(&camsys_platform_driver);
return 0;
}
由上述代码我们可以知道在camsys_platform_init中实现了自旋锁的初始化,链表头的初始化,以及平台设备驱动的注册等。
(2) platform_driver结构体定义
camsys_platform_driver结构体的定义如下:
static struct platform_driver camsys_platform_driver = {
.driver = {
.name = CAMSYS_PLATFORM_DRV_NAME,
.of_match_table = of_match_ptr(cif_of_match),
},
.probe = camsys_platform_probe,
.remove = (camsys_platform_remove),
};
有上述代码可知,camsys_drv.o模块加载的时候,主要是注册了一个platform_driver结构体。在Linux内核中,platform总线在加载设备或者驱动的时候,都会有一个探测过程,探测是否有匹配的驱动或者设备,匹配成功则会执行其中的 .probe 函数,其中会优先通过 .of_match_table 匹配,如果匹配不成功,再使用 .name 进行匹配。
需要的 .name 定义如下:
#define CAMSYS_PLATFORM_DRV_NAME "RockChip-CamSys"
需要的 .of_match_table 定义如下:
static const struct of_device_id cif_of_match[] = {
{
.compatible = "rockchip,isp" },
{
/* sentinel */ }
};
MODULE_DEVICE_TABLE(of, cif_of_match);
有上述定义可知,驱动中的 .of_match_table 需要和DTS里面的 .compatible = “rockchip,isp” 进行匹配,匹配成功了会调用platform_driver中的probe函数。
(3) DTS设置
相应的dts文件存放路径:
./kernel/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi
dts文件里的设置如下:
isp0: isp@ff910000 {
compatible = "rockchip,rk3399-isp", "rockchip,isp";
......
status = "disabled";
};
isp0: isp@ff920000 {
compatible = "rockchip,rk3399-isp", "rockchip,isp";
......
status = "disabled";
};
如果需要 .of_match_table 能和DTS匹配上,需要将status的状态从disabled改成okay。即:
isp0: isp@ff910000 {
compatible = "rockchip,rk3399-isp", "rockchip,isp";
......
status = "okay";
};
isp0: isp@ff920000 {
compatible = "rockchip,rk3399-isp", "rockchip,isp";
......
status = "okay";
};
(4) 执行probe函数
platform设备与驱动一旦匹配成功,将会执行驱动的probe函数,camsys驱动的probe函数定义如下,省略掉了部分非核心的代码:
static int camsys_platform_probe(struct platform_device *pdev)
{
......
/* 获取dts文件中的compatible的节点并打印出来 */
err = of_property_read_string(dev->of_node, "compatible", &compatible);
if (err < 0) {
camsys_err("g