背景:
kernel中的component框架是为了subsystem能够按照一定的顺序初始化设备而提出的架构。subsystem中由较多设备模块组成(display subsystem 即由CRCT、encoder、connecter、gsm、等模块组成),而内核加载每个模块时间不定。则需要component框架来保证需最后初始化的设备加载前,所需设备全部加载完毕。
架构描述:
在component中,包含两个基本概念,master和component。master是设备树中的“超级设备(superdevice)”,负责管理该超级设备下的普通设备。component是由master管理的普通设备,要先初始化。
master在设备树中一般为XXX-subsystem节点,如display-subsystem。节点有ports属性,属性里存有该master应该关联的普通设备,如ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;。
display-subsystem {
compatible = "fsl,imx-display-subsystem";
ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>;
};
component是普通的设备节点,其下有与master的prots属性值一样的节点,如ipu1_di0的节点。通过属性值这个字段名,把超级设备与普通设备关联起来。
ipu1: ipu@02400000 {
...
ipu1_di0: port@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
ipu1_di0_disp0: disp0-endpoint {
};
主要文件:
/driver/base/component.c文件包含了主要逻辑。
设备的初始化流程:
初始化分为两部分:
1、master即超级设备,执行probe函数时使用component_master_add_with_match函数注册自己到component框架中。
2、component即普通设备,执行probe函数时使用component_add函数注册自己到component框架中。
两种流程先后顺序并无要求,可随意顺序。每一个设备加入到框架中,框架就尝试进行匹配,当master匹配上所有component后(匹配到dts中prots中的所有组件?),会调用master的bind回调(rockchip_drm_bind),开始按顺序进行初始化。保证了当所有子设备全部probe成功后再执行初始化操作。
1、Master设备的初始化流程
首先probe函数中定义一个component_match结构体的对象指针match。match是一个存储子节点的数组。遍历超级设备节点下的"ports"属性,每解析出1个属性值。
调用component_match_add函数,在match中添加一个compare数组成员,还会再将每个属性值关联的设备添加到match中。
返回probe函数,调用component_master_add_with_match函数,注册该master,在该函数中调用try_to_bring_up_master函数,尝试初始化该master。
1.1 Master设备probe函数
首先probe函数中定义一个component_match结构体的对象指针match。match是一个存储子节点的数组。遍历超级设备节点下的"ports"属性,每解析出1个属性值。调用component_match_add函数,在match中添加一个compare数组成员,还会再将每个属性值关联的设备添加到match中。返回probe函数,调用component_master_add_with_match函数,注册该