1,调用流程
omap_dss_bus_register()注册一个总线:static struct bus_type dss_bus_type = {
.name = "omapdss",
.match = dss_bus_match,
.dev_attrs = default_dev_attrs,
.drv_attrs = default_drv_attrs,
};
取名为omapdss,同时提供了match函数,这个函数主要是判断omap_dss_device与device_driver是否为同一个名字,如果是则返回1(真),不是则返回0(假)。
static int __init omap_dss_init2(void)
{
return platform_driver_register(&omap_dss_driver);
}
注册了platform_driver:
static struct platform_driver omap_dss_driver = {
.probe = omap_dss_probe,
.remove = omap_dss_remove,
.shutdown = omap_dss_shutdown,
.suspend = omap_dss_suspend,
.resume = omap_dss_resume,
.driver = {
.name = "omapdss",
.owner = THIS_MODULE,
},
};
其中driver的name取名为omapdss,并且提供了probe的方法。omap_dss_probe。static void __init omap3_stalker_init(void)函数在init段中,启动时候有内核自行调用运行。这个函数中调用了:platform_add_devices()函数。并且参数为:omap3_stalker_devices。展开这个参数,发现参数为结构体数组,描述了显示设备的类型。
static struct platform_device *omap3_stalker_devices[] __initdata = {
&omap3_stalker_dss_device,
&omap3stalker_camkit_device,
};
其中omap3_stalker_dss_device为platform_device。这个结构体中platform_data字段初始化为:omap_dss_board_info,这种过程中有paltform类型过渡到omap_dss_xxx类型。同时再窥探内部的结构体后发现出现了omap_dss_device变量。并且这个变量初始化为omap类型的dss各种显示设备。
2,逻辑关系
以上介绍了paltform到omap_dss_xxx类型的变化过程,同时也说明了函数调用的流程。接下来就要仔细看看dss设备的逻辑关系了。有了platform_driver和platform_device这两个配对的结构体后,就要使用match函数了。类似于:dss_bus_match,函数比较了两个结构体中name字段,若是成功则调用相关的probe函数。若是失败怎返回假。这里涉及到了linux设备驱动管理的相关概念,可以在网上搜索一下相关的资料。这里不在复述。应为name字段都为“omapdss”因此linux提供的总线match会比较成功,进而调用驱动的probe函数:omap_dss_probe。
到了omap_dss_probe函数,驱动提供了探测逻辑。此函数中又会调用omap_dss_register_device(),参数为omap_dss_device *dssdev = pdata->devices[i];其中pdata为pdev->dev.platform_data。如果仔细阅读代码后会发现这里出现的platform_data为:omap3_stalker_dss_data,(补充一句:platform_data的注释为 /* Platform specific data, device core doesn't touch it */,这是device结构体中的私有变量,有平台驱动提供者自行控制)。从platform到omap_dss_xxx相关的逻辑流程体现在结构体的封装上,关系如下:
static struct omap_dss_device *omap3_stalker_dss_devices[] = {
&omap3_stalker_lcd070_device,
&omap3_stalker_lcd043_device,
&omap3_stalker_tv_device,
&omap3_stalker_dvi_device,
};
static struct omap_dss_board_info omap3_stalker_dss_data = {
.num_devices = ARRAY_SIZE(omap3_stalker_dss_devices),
.devices = omap3_stalker_dss_devices,
.default_device = &omap3_stalker_dvi_device,
};
static struct platform_device omap3_stalker_dss_device = {
.name = "omapdss",
.id = -1,
.dev = {
.platform_data = &omap3_stalker_dss_data,
},
};
终于发现了omap_dss_device。回到omap_dss_probe函数中,此函数调用了omap_dss_register_device。对与dss的设备注册,并且在总线omapdss上。这里仅仅是注册,一定要配对成功才会调用probe驱动探测。omapdss的总线这时候正真出现并且其中的match函数发挥作用。此处的作用类似linux的设备与驱动管理提供的match。
有了omap_dss_device自然一定要有omap_dss_driver。并且一样要提供探测函数。以上的经验告诉我们match的name字段很重要。match成功与否是否能找到探测函数完全是根据name来判断。搜索name字段后发现了一下相关的结构体,分别有在其他的驱动模块中定义,这里举其中一个列子来反映:omap3_stalker_lcd070_device。在panel-at070tn13.c中发现了omap_dss_register_driver(&at070tn13_panel);具体参数看文件中描述,这里不再复述。随后找到了驱动提供的探测函at070tn13_panel_probe。
3,总结
linux_system_bus:
|-platform_device (omapdss device)
|-platform_driver (omapdss driver probe)
platform_driver:
|-omap_dss_device (display driver)
|-omap_dss_driver (display driver probe)
omap_dss_driver:
|-lcd_device
|-dvi_device
|-venc_device
|-digi_devide
system_bus
|-omapdss_bus
| |-lcd
| |-dvi
| |- ...
| |- ...
| |-venc
|
|
|- ...
|- ...
|-xxxx_bus
好久没有写blog了,最后一次发现我的台式机硬盘无法正常使用,感到很遗憾,里面有很多资料,很多很多很多 无法再使用了