uclass和udevice和udriver关系
struct uclass结构的定义如下:
35 struct uclass {
36 void *priv;
37 struct uclass_driver *uc_drv;
38 struct list_head dev_head;
39 struct list_head sibling_node;
40 };
struct udevice结构的定义如下:
128 struct udevice {
129 const struct driver *driver;
130 const char *name;
131 void *platdata;
132 void *parent_platdata;
133 void *uclass_platdata;
134 ofnode node;
135 ulong driver_data;
136 struct udevice *parent;
137 void *priv;
138 struct uclass *uclass;
139 void *uclass_priv;
140 void *parent_priv;
141 struct list_head uclass_node;
142 struct list_head child_head;
143 struct list_head sibling_node;
144 uint32_t flags;
145 int req_seq;
146 int seq;
147 #ifdef CONFIG_DEVRES
148 struct list_head devres_head;
149 #endif
150 };
gd_t结构的uclass_root链表。
27 typedef struct global_data {
28 bd_t *bd;
29 unsigned long flags;
30 unsigned int baudrate;
31 unsigned long cpu_clk; /* CPU clock in Hz! */
32 unsigned long bus_clk;
.........
65 #ifdef CONFIG_DM
66 struct udevice *dm_root; /* Root instance for Driver Model */
67 struct udevice *dm_root_f; /* Pre-relocation root instance */
68 struct list_head uclass_root; /* Head of core tree */
69 #endif
......
} gd_t;
说明:
- uclass的sibling_node成员连接到结构gd_t的uclass_root,实现uclass连接到gd_t。
- udevice的uclass_node成员连接到结构uclass的dev_head,实现udevice挂载到uclass。
uclass_find函数的定义:
23 struct uclass *uclass_find(enum uclass_id key)
24 {
25 struct uclass *uc;
26
27 if (!gd->dm_root)
28 return NULL;
29 /*
30 * TODO([email protected]): Optimise this, perhaps moving the found
31 * node to the start of the list, or creating a linear array mapping
32 * id to node.
33 */
34 list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
35 if (uc->uc_drv->id == key)
36 return uc;
37 }
38
39 return NULL;
40 }
说明:
不同种类的uclass都是挂在gd->uclass_root上,通过uclass中的uc_drv->id等于index来区分不同的uclass。
这样可以通过index找到对应的uclass,然后把udevice挂到uclass上。
2. 添加udevice到uclass
uclass_bind_device()函数
536 int uclass_bind_device(struct udevice *dev)
537 {
538 struct uclass *uc;
539 int ret;
540
541 uc = dev->uclass;
542 list_add_tail(&dev->uclass_node, &uc->dev_head);
543
544 if (dev->parent) {
545 struct uclass_driver *uc_drv = dev->parent->uclass->uc_drv;
546
547 if (uc_drv->child_post_bind) {
548 ret = uc_drv->child_post_bind(dev);
549 if (ret)
550 goto err;
551 }
552 }
553
554 return 0;
555 err:
556 /* There is no need to undo the parent's post_bind call */
557 list_del(&dev->uclass_node);
558
559 return ret;
560 }
在542行,通过list_add_tail实现device到uclass的挂载。
3. 加载设备驱动
uclass_get_device函数:
398 int uclass_get_device(enum uclass_id id, int index, struct udevice **devp)
399 {
400 struct udevice *dev;
401 int ret;
402
403 *devp = NULL;
404 ret = uclass_find_device(id, index, &dev);
405 return uclass_get_device_tail(dev, ret, devp);
406 }
uclass_find_device函数
175 int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
176 {
177 struct uclass *uc;
178 struct udevice *dev;
179 int ret;
180
181 *devp = NULL;
182 ret = uclass_get(id, &uc);
183 if (ret)
184 return ret;
185 if (list_empty(&uc->dev_head))
186 return -ENODEV;
187
188 list_for_each_entry(dev, &uc->dev_head, uclass_node) {
189 if (!index--) {
190 *devp = dev;
191 return 0;
192 }
193 }
194
195 return -ENODEV;
196 }
4. UCLASS_SERIAL
在include/dm/uclass-id.h定义
ddddd
UCLASS_SERIAL = 59