initf_dm//执行bind操作,初始化一个dm模型的树形结构
dm_init_and_scan(true)//初始化根节点设备,并bind根节点的带有u-boot,dm-pre-reloc属性的一级子节点。
dm_init//将根节点绑定到gd->dm_root上,初始化根节点设备
dm_scan_platdata//搜索使用宏U_BOOT_DEVICE定义的设备进行驱动匹配,也就是bind子节点
dm_extended_scan_fdt//在其他地方(设备树)搜索设备并进行驱动匹配,然后bind
dm_scan_fdt//在设备树种搜索设备并进行驱动匹配,然后bind
dm_scan_fdt_node//具体绑定设备的入口,在该函数中会确定设备是否具有boot,dm-pre-reloc属性,如果没有则不会绑定
lists_bind_fdt//搜索可以匹配到该设备的驱动
device_bind_with_driver_data//如果匹配到进行绑定
device_bind_common//匹配设备和驱动,并将设备节点和parent节点建立联系,也就是建立树形结构
uclass_bind_device//将该设备挂在对应的U_CLASS链表上
drv->bind(dev)//设备驱动的bind接口函数
parent->driver->child_post_bind(dev)//父节点驱动的child_post_bind接口函数
uc->uc_drv->post_bind//设备所属类的驱动的post_bind接口函数(具体的设备节点就是在这个接口下在soc下进行展开的)
gd->dm_root_f = gd->dm_root; gd->dm_root = NULL;
dm_init_and_scan(false)//初始化根节点设备,并bind根节点的所有子节点
************省略,见initf_dm函数流程
&fmc {
pinctrl-0 = <&fmc_pins>;
pinctrl-names = "default";
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
/* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */
bank1: bank@0 {
st,sdram-control = /bits/ 8 ;
st,sdram-timing = /bits/ 8 ;
/* refcount = (64msec/total_row_sdram)*freq - 20 */
st,sdram-refcount = < 1421 >;
};
bank3: stm32_nand {
reg = <0xA0000080 0x20>;
/*Nand flash configuretion from flash datasheet MT29F4G08ABADA*/
compatible = "micron,mt29f4g", "st,nand-flash";
st,nand-control = /bits/ 8 ;
st,nand-timing = /bits/ 8 ;
u-boot,dm-pre-reloc;
};
};
root
\
soc
\
fmc
\
stm32_nand
root
\
soc
\
fmc
dev_for_each_subnode(bank_node, dev) {
/* extract the bank index from DT */
bank_name = (char *)ofnode_get_name(bank_node);
if (!strncmp("stm32_nand", bank_name, strlen("stm32_nand")))//iysheng
{
lists_bind_fdt(dev, bank_node, NULL);
continue;
}
}
static int stm32_fmc_probe(struct udevice *dev)
{
******省略一些内容,和sdram初始化相关的内容
if (device_has_children(dev))
{
struct udevice * child_devp;
int index = 0;
while(!device_get_child(dev, index++, &child_devp)) {
ret = device_probe(child_devp);
if (ret < 0)
break;
}
}
}
int dram_init(void)
uclass_get_device(UCLASS_RAM, 0, &dev)
uclass_find_device(id, index, &dev)
uclass_get_device_tail(dev, ret, devp)
device_probe(dev)
device_probe(dev->parent)//递归probe父节点
uclass_resolve_seq//父节点都probe之后,会分配一个seq给该设备
dev->flags |= DM_FLAG_ACTIVATED//设置该设备的flag为激活状态
pinctrl_select_state(dev, "default")//和引脚相关的初始化设置<需要进一步分析>
dev->parent->driver->child_pre_probe(dev)//执行父节点驱动的child_pre_probe接口函数
drv->ofdata_to_platdata(dev)//执行设备驱动的ofdata_to_platdata接口函数
clk_set_defaults(dev)//设备时钟相关的设置
drv->probe(dev)//调用设备驱动的probe接口函数
uclass_post_probe_device(dev)//调用所属CLASS驱动的post_probe接口函数