u-boot device_probe函数

 

 

 

 

 

  1. 分配设备的私有数据
  2. 对父设备probe,执行probe device之前uclass需要调用的一些函数
  3. 调用driver的ofdata_to_platdata,将dts信息转化为设备的平台数据
  4. 调用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的flag的标志
    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;
}
posted @ 2022-02-21 20:29  liujunhuasd  阅读(748)  评论(0编辑  收藏  举报