u-boot uclass操作函数


       
  • struct uclass *uclass_find(enum uclass_id key)

{     list_for_each_entry(uc, gd->uclass_root, sibling_node)  }  
  • static int uclass_add(enum uclass_id id, struct uclass **ucp)

{     struct uclass_driver *uc_drv;     struct uclass *uc;     int ret;     *ucp = NULL; //获得类驱动     uc_drv = lists_uclass_lookup(id); //分配类设备空间     uc = calloc(1, sizeof(*uc));   //根据设备类驱动uc_drv->priv_auto来设置类设备私用数据uc->priv_ )     uclass_set_priv(uc, ptr); //设置设备类的驱动程序     uc->uc_drv = uc_drv;     INIT_LIST_HEAD(&uc->sibling_node);     INIT_LIST_HEAD(&uc->dev_head); //设置类设备的链接,添加在gd->uclass_root之后     list_add(&uc->sibling_node, DM_UCLASS_ROOT_NON_CONST);

//调用类设备的初始化操作

        ret = uc_drv->init(uc);             *ucp = uc;
  • int uclass_destroy(struct uclass *uc)

{     struct uclass_driver *uc_drv;     struct udevice *dev;     int ret;

    while (!list_empty(&uc->dev_head)) {

        dev = list_first_entry(&uc->dev_head, struct udevice,                        uclass_node);         ret = device_remove(dev, DM_REMOVE_NORMAL | DM_REMOVE_NO_PD);         if (ret)             return log_msg_ret("remove", ret);         ret = device_unbind(dev);         if (ret)             return log_msg_ret("unbind", ret);     }     uc_drv = uc->uc_drv;     if (uc_drv->destroy)         uc_drv->destroy(uc);     list_del(&uc->sibling_node);     if (uc_drv->priv_auto)         free(uclass_get_priv(uc));     free(uc);     return 0; }
  • int uclass_get(enum uclass_id id, struct uclass **ucp)

{     struct uclass *uc;

    if (!gd->uclass_root)

        return -EDEADLK;     *ucp = NULL;     uc = uclass_find(id);     if (!uc) {         if (CONFIG_IS_ENABLED(OF_PLATDATA_INST))             return -ENOENT;         return uclass_add(id, ucp);     }     *ucp = uc;

    return 0;

}
  • const char *uclass_get_name(enum uclass_id id)

    struct uclass *uc;     if (uclass_get(id, &uc))         return NULL;     return uc->uc_drv->name; } void *uclass_get_priv(const struct uclass *uc) {     return uc->priv_; } void uclass_set_priv(struct uclass *uc, void *priv) {     uc->priv_ = priv; } enum uclass_id uclass_get_by_name(const char *name) {     int i;     for (i = 0; i < UCLASS_COUNT; i++) {         struct uclass_driver *uc_drv = lists_uclass_lookup(i);         if (uc_drv && !strcmp(uc_drv->name, name))             return i;     }     return UCLASS_INVALID; } int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp) {     struct udevice *iter;     struct uclass *uc = dev->uclass;     int i = 0;     if (list_empty(&uc->dev_head))         return -ENODEV;     uclass_foreach_dev(iter, uc) {         if (iter == dev) {             if (ucp)                 *ucp = uc;             return i;         }         i++;     }     return -ENODEV; }

3、通过uclass来find设备device的函数

int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) {     struct uclass *uc;     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_get(id, &uc);     if (ret)         return ret;     if (list_empty(&uc->dev_head))         return -ENODEV;     uclass_foreach_dev(dev, uc) {         if (!index--) {             *devp = dev;             return 0;         }     }     return -ENODEV; } int uclass_find_first_device(enum uclass_id id, struct udevice **devp) {     struct uclass *uc;     int ret;     *devp = NULL;     ret = uclass_get(id, &uc);     if (ret)         return ret;     if (list_empty(&uc->dev_head))         return 0;     *devp = list_first_entry(&uc->dev_head, struct udevice, uclass_node);     return 0; } int uclass_find_next_device(struct udevice **devp) {     struct udevice *dev = *devp;     *devp = NULL;     if (list_is_last(&dev->uclass_node, &dev->uclass->dev_head))         return 0;     *devp = list_entry(dev->uclass_node.next, struct udevice, uclass_node);     return 0; } int uclass_find_device_by_name(enum uclass_id id, const char *name,                    struct udevice **devp) {     struct uclass *uc;     struct udevice *dev;     int ret;     *devp = NULL;     if (!name)         return -EINVAL;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         if (!strcmp(dev->name, name)) {             *devp = dev;             return 0;         }     }     return -ENODEV; } int uclass_find_next_free_seq(struct uclass *uc) {     struct udevice *dev;     int max = -1;     /* If using aliases, start with the highest alias value */     if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&         (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS))         max = dev_read_alias_highest_id(uc->uc_drv->name);     /* Avoid conflict with existing devices */     list_for_each_entry(dev, &uc->dev_head, uclass_node) {         if (dev->seq_ > max)             max = dev->seq_;     }     /*      * At this point, max will be -1 if there are no existing aliases or      * devices      */     return max + 1; } int uclass_find_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) {     struct uclass *uc;     struct udevice *dev;     int ret;     *devp = NULL;     log_debug("%d\n", seq);     if (seq == -1)         return -ENODEV;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         log_debug("   - %d '%s'\n", dev->seq_, dev->name);         if (dev->seq_ == seq) {             *devp = dev;             log_debug("   - found\n");             return 0;         }     }     log_debug("   - not found\n");     return -ENODEV; } int uclass_find_device_by_of_offset(enum uclass_id id, int node,                     struct udevice **devp) {     struct uclass *uc;     struct udevice *dev;     int ret;     *devp = NULL;     if (node < 0)         return -ENODEV;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         if (dev_of_offset(dev) == node) {             *devp = dev;             return 0;         }     }     return -ENODEV; } int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,                  struct udevice **devp) {     struct uclass *uc;     struct udevice *dev;     int ret;     log(LOGC_DM, LOGL_DEBUG, "Looking for %s\n", ofnode_get_name(node));     *devp = NULL;     if (!ofnode_valid(node))         return -ENODEV;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         log(LOGC_DM, LOGL_DEBUG_CONTENT, "      - checking %s\n",             dev->name);         if (ofnode_equal(dev_ofnode(dev), node)) {             *devp = dev;             goto done;         }     }     ret = -ENODEV; done:     log(LOGC_DM, LOGL_DEBUG, "   - result for %s: %s (ret=%d)\n",         ofnode_get_name(node), *devp ? (*devp)->name : "(none)", ret);     return ret; } #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent,                   const char *name, struct udevice **devp) {     struct udevice *dev;     struct uclass *uc;     int find_phandle;     int ret;     *devp = NULL;     find_phandle = dev_read_u32_default(parent, name, -1);     if (find_phandle <= 0)         return -ENOENT;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         uint phandle;         phandle = dev_read_phandle(dev);         if (phandle == find_phandle) {             *devp = dev;             return 0;         }     }     return -ENODEV; } #endif

4、通过uclass来get设备device的函数

int uclass_get_device_by_driver(enum uclass_id id,                 const struct driver *find_drv,                 struct udevice **devp) {     struct udevice *dev;     struct uclass *uc;     int ret;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         if (dev->driver == find_drv)             return uclass_get_device_tail(dev, 0, devp);     }     return -ENODEV; } int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp) {     if (ret)         return ret;     assert(dev);     ret = device_probe(dev);     if (ret)         return ret;     *devp = dev;     return 0; } int uclass_get_device(enum uclass_id id, int index, struct udevice **devp) {     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_find_device(id, index, &dev);     return uclass_get_device_tail(dev, ret, devp); } int uclass_get_device_by_name(enum uclass_id id, const char *name,                   struct udevice **devp) {     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_find_device_by_name(id, name, &dev);     return uclass_get_device_tail(dev, ret, devp); } int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) {     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_find_device_by_seq(id, seq, &dev);     return uclass_get_device_tail(dev, ret, devp); } int uclass_get_device_by_of_offset(enum uclass_id id, int node,                    struct udevice **devp) {     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_find_device_by_of_offset(id, node, &dev);     return uclass_get_device_tail(dev, ret, devp); } int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,                 struct udevice **devp) {     struct udevice *dev;     int ret;     log(LOGC_DM, LOGL_DEBUG, "Looking for %s\n", ofnode_get_name(node));     *devp = NULL;     ret = uclass_find_device_by_ofnode(id, node, &dev);     log(LOGC_DM, LOGL_DEBUG, "   - result for %s: %s (ret=%d)\n",         ofnode_get_name(node), dev ? dev->name : "(none)", ret);     return uclass_get_device_tail(dev, ret, devp); } #if CONFIG_IS_ENABLED(OF_CONTROL) int uclass_get_device_by_phandle_id(enum uclass_id id, uint phandle_id,                     struct udevice **devp) {     struct udevice *dev;     struct uclass *uc;     int ret;     *devp = NULL;     ret = uclass_get(id, &uc);     if (ret)         return ret;     uclass_foreach_dev(dev, uc) {         uint phandle;         phandle = dev_read_phandle(dev);         if (phandle == phandle_id) {             *devp = dev;             return uclass_get_device_tail(dev, ret, devp);         }     }     return -ENODEV; } int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent,                  const char *name, struct udevice **devp) {     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_find_device_by_phandle(id, parent, name, &dev);     return uclass_get_device_tail(dev, ret, devp); } #endif int uclass_first_device(enum uclass_id id, struct udevice **devp) {     struct udevice *dev;     int ret;     *devp = NULL;     ret = uclass_find_first_device(id, &dev);     if (!dev)         return 0;     return uclass_get_device_tail(dev, ret, devp); } int uclass_first_device_err(enum uclass_id id, struct udevice **devp) {     int ret;     ret = uclass_first_device(id, devp);     if (ret)         return ret;     else if (!*devp)         return -ENODEV;     return 0; } int uclass_next_device(struct udevice **devp) {     struct udevice *dev = *devp;     int ret;     *devp = NULL;     ret = uclass_find_next_device(&dev);     if (!dev)         return 0;     return uclass_get_device_tail(dev, ret, devp); } int uclass_next_device_err(struct udevice **devp) {     int ret;     ret = uclass_next_device(devp);     if (ret)         return ret;     else if (!*devp)         return -ENODEV;     return 0; } int uclass_first_device_check(enum uclass_id id, struct udevice **devp) {     int ret;     *devp = NULL;     ret = uclass_find_first_device(id, devp);     if (ret)         return ret;     if (!*devp)         return 0;     return device_probe(*devp); } int uclass_next_device_check(struct udevice **devp) {     int ret;     ret = uclass_find_next_device(devp);     if (ret)         return ret;     if (!*devp)         return 0;     return device_probe(*devp); } int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,                 struct udevice **devp) {     struct udevice *dev;     struct uclass *uc;     uclass_id_foreach_dev(id, dev, uc) {         if (dev_get_driver_data(dev) == driver_data) {             *devp = dev;             return device_probe(dev);         }     }     return -ENODEV; } int uclass_bind_device(struct udevice *dev) {     struct uclass *uc;     int ret;     uc = dev->uclass;     list_add_tail(&dev->uclass_node, &uc->dev_head);     if (dev->parent) {         struct uclass_driver *uc_drv = dev->parent->uclass->uc_drv;         if (uc_drv->child_post_bind) {             ret = uc_drv->child_post_bind(dev);             if (ret)                 goto err;         }     }     return 0; err:     /* There is no need to undo the parent's post_bind call */     list_del(&dev->uclass_node);     return ret; } #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) int uclass_unbind_device(struct udevice *dev) {     struct uclass *uc;     int ret;     uc = dev->uclass;     if (uc->uc_drv->pre_unbind) {         ret = uc->uc_drv->pre_unbind(dev);         if (ret)             return ret;     }     list_del(&dev->uclass_node);     return 0; } #endif int uclass_pre_probe_device(struct udevice *dev) {     struct uclass_driver *uc_drv;     int ret;     uc_drv = dev->uclass->uc_drv;     if (uc_drv->pre_probe) {         ret = uc_drv->pre_probe(dev);         if (ret)             return ret;     }     if (!dev->parent)         return 0;     uc_drv = dev->parent->uclass->uc_drv;     if (uc_drv->child_pre_probe) {         ret = uc_drv->child_pre_probe(dev);         if (ret)             return ret;     }     return 0; } int uclass_post_probe_device(struct udevice *dev) {     struct uclass_driver *uc_drv;     int ret;     if (dev->parent) {         uc_drv = dev->parent->uclass->uc_drv;         if (uc_drv->child_post_probe) {             ret = uc_drv->child_post_probe(dev);             if (ret)                 return ret;         }     }     uc_drv = dev->uclass->uc_drv;     if (uc_drv->post_probe) {         ret = uc_drv->post_probe(dev);         if (ret)             return ret;     }     return 0; } #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE) int uclass_pre_remove_device(struct udevice *dev) {     struct uclass *uc;     int ret;     uc = dev->uclass;     if (uc->uc_drv->pre_remove) {         ret = uc->uc_drv->pre_remove(dev);         if (ret)             return ret;     }     return 0; } #endif int uclass_probe_all(enum uclass_id id) {     struct udevice *dev;     int ret;     ret = uclass_first_device(id, &dev);     if (ret || !dev)         return ret;     /* Scanning uclass to probe all devices */     while (dev) {         ret = uclass_next_device(&dev);         if (ret)             return ret;     }     return 0; } UCLASS_DRIVER(nop) = {     .id     = UCLASS_NOP,     .name       = "nop", };

相关