u-boot device_probe函数
- 分配设备的私有数据
- 对父设备probe,执行probe device之前uclass需要调用的一些函数
- 调用driver的ofdata_to_platdata,将dts信息转化为设备的平台数据
- 调用driver的probe函数,执行probe device之后uclass需要调用的一些函数
int device_probe(struct udevice *dev)
{
const struct driver *drv;
int ret;
//获得设备的驱动指针
drv = dev->driver;
//分配设备私有数据 ret = device_of_to_plat(dev);
/* Ensure all parents are probed */
if (dev->parent) {
ret = device_probe(dev->parent);
if (ret)
goto fail;
if (dev_get_flags(dev) & DM_FLAG_ACTIVATED)
return 0;
}
dev_or_flags(dev, DM_FLAG_ACTIVATED);
//设备的设定管脚的状态
if (dev->parent && device_get_uclass_id(dev) != UCLASS_PINCTRL)
pinctrl_select_state(dev, "default");
//设备的电源情况
if (CONFIG_IS_ENABLED(POWER_DOMAIN) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) &&
!(drv->flags & DM_FLAG_DEFAULT_PD_CTRL_OFF)) {
ret = dev_power_domain_on(dev);
if (ret)
goto fail;
}
//
ret = device_get_dma_constraints(dev);
if (ret)
goto fail;
ret = uclass_pre_probe_device(dev);
if (ret)
goto fail;
if (dev->parent && dev->parent->driver->child_pre_probe) {
ret = dev->parent->driver->child_pre_probe(dev);
if (ret)
goto fail;
}
/* Only handle devices that have a valid ofnode */
if (dev_has_ofnode(dev)) {
/*
* Process 'assigned-{clocks/clock-parents/clock-rates}'
* properties
*/
ret = clk_set_defaults(dev, CLK_DEFAULTS_PRE);
if (ret)
goto fail;
}
if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto fail;
}
ret = uclass_post_probe_device(dev);
if (ret)
goto fail_uclass;
if (dev->parent && device_get_uclass_id(dev) == UCLASS_PINCTRL)
pinctrl_select_state(dev, "default");
return 0;
fail_uclass:
if (device_remove(dev, DM_REMOVE_NORMAL)) {
dm_warn("%s: Device '%s' failed to remove on error path\n",
__func__, dev->name);
}
fail:
dev_bic_flags(dev, DM_FLAG_ACTIVATED);
device_free(dev);
return ret;
}