U-BOOT驱动模型(DEVICE 模型)

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;

说明:

  1. uclass的sibling_node成员连接到结构gd_t的uclass_root,实现uclass连接到gd_t。
  2. 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

发布了112 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chengbeng1745/article/details/101670764
今日推荐