probe调用过程

来源:互联网 发布:知网和知乎 编辑:程序博客网 时间:2024/05/03 06:24
这几天搞TI的vpfe,里面设备的注册使用platform,平台设备注册方式来注册的。一直都知道

[cpp] view plain copy
print?
  1. 112 struct device_driver {  
  2. 113     const char      * name;  
  3. 114     struct bus_type     * bus;  
  4. 115   
  5. 116     struct completion   unloaded;  
  6. 117     struct kobject      kobj;  
  7. 118     struct klist        klist_devices;  
  8. 119     struct klist_node   knode_bus;  
  9. 120   
  10. 121     struct module       * owner;  
  11. 122   
  12. 123     int (*probe)    (struct device * dev);  
  13. 124     int (*remove)   (struct device * dev);  
  14. 125     void    (*shutdown) (struct device * dev);  
  15. 126     int (*suspend)  (struct device * dev, pm_message_t state);  
  16. 127     int (*resume)   (struct device * dev);  
  17. 128 };  

里的probe函数,但是不知道是何时被调用的。经过跟踪代码,在module_init(vpfe_init);模块初始化的时候,vpfe_init函数中调用了

[cpp] view plain copy
print?
  1. 4775     /* Register driver to the kernel */  
  2. 4776     err = driver_register(&vpfe_driver);  

这里
 err = driver_register(&vpfe_driver);
的原型为:

[cpp] view plain copy
print?
  1. 171 int driver_register(struct device_driver * drv)  
  2. 172 {              
  3. 173     if ((drv->bus->probe && drv->probe) ||  
  4. 174         (drv->bus->remove && drv->remove) ||  
  5. 175         (drv->bus->shutdown && drv->shutdown)) {  
  6. 176         printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods/n", drv->name);  
  7. 177     }          
  8. 178     klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);  
  9. 179     init_completion(&drv->unloaded);  
  10. 180     return bus_add_driver(drv);  
  11. 181 }  

跟踪bus_add_driver(drv);得到bus_add_driver(struct device_driver * drv)的原型:

[cpp] view plain copy
print?
  1. 479 int bus_add_driver(struct device_driver * drv)  
  2. 480 {     
  3. 481     struct bus_type * bus = get_bus(drv->bus);  
  4. 482     int error = 0;  
  5. 483   
  6. 484     if (bus) {  
  7. 485         pr_debug("bus %s: add driver %s/n", bus->name, drv->name);  
  8. 486         error = kobject_set_name(&drv->kobj, "%s", drv->name);  
  9. 487         if (error) {  
  10. 488             put_bus(bus);  
  11. 489             return error;  
  12. 490         }  
  13. 491         drv->kobj.kset = &bus->drivers;  
  14. 492         if ((error = kobject_register(&drv->kobj))) {  
  15. 493             put_bus(bus);  
  16. 494             return error;  
  17. 495         }  
  18. 496   
  19. 497         driver_attach(drv);  
  20. 498         klist_add_tail(&drv->knode_bus, &bus->klist_drivers);  
  21. 499         module_add_driver(drv->owner, drv);  
  22. 500           
  23. 501         driver_add_attrs(bus, drv);  
  24. 502         add_bind_files(drv);  
  25. 503     }          
  26. 504     return error;  
  27. 505 }    
  28.   
  29. 其中190 void driver_attach(struct device_driver * drv)  
  30. 191 {  
  31. 192     bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);  
  32. 193 }    
  33.   
  34. __driver_attach是一个函数,原型:  
  35.   
  36. 155 static int __driver_attach(struct device * dev, void * data)  
  37. 156 {  
  38. 157     struct device_driver * drv = data;  
  39. 158   
  40. 159     /* 
  41. 160      * Lock device and try to bind to it. We drop the error 
  42. 161      * here and always return 0, because we need to keep trying 
  43. 162      * to bind to devices and some drivers will return an error 
  44. 163      * simply if it didn't support the device. 
  45. 164      * 
  46. 165      * driver_probe_device() will spit a warning if there 
  47. 166      * is an error. 
  48. 167      */  
  49. 168   
  50. 169     if (dev->parent)    /* Needed for USB */  
  51. 170         down(&dev->parent->sem);  
  52. 171     down(&dev->sem);  
  53. 172     if (!dev->driver)  
  54. 173         driver_probe_device(drv, dev);  
  55. 174     up(&dev->sem);  
  56. 175     if (dev->parent)  
  57. 176         up(&dev->parent->sem);  
  58. 177       
  59. 178     return 0;  
  60. 179 }     

这里调用了 driver_probe_device(drv, dev);
原型:

[cpp] view plain copy
print?
  1. 76 int driver_probe_device(struct device_driver * drv, struct device * dev)  
  2.  77 {  
  3.  78     int ret = 0;  
  4.  79   
  5.  80     if (drv->bus->match && !drv->bus->match(dev, drv))  
  6.  81         goto Done;  
  7.  82   
  8.  83     pr_debug("%s: Matched Device %s with Driver %s/n",  
  9.  84          drv->bus->name, dev->bus_id, drv->name);  
  10.  85     dev->driver = drv;  
  11.  86     if (dev->bus->probe) {  
  12.  87         ret = dev->bus->probe(dev);  
  13.  88         if (ret) {  
  14.  89             dev->driver = NULL;  
  15.  90             goto ProbeFailed;  
  16.  91         }  
  17.  92     } else if (drv->probe) {  
  18.  93         ret = drv->probe(dev);  
  19.  94         if (ret) {  
  20.  95             dev->driver = NULL;  
  21.  96             goto ProbeFailed;  
  22.  97         }  
  23.  98     }  
  24.  99     device_bind_driver(dev);  
  25. 100     ret = 1;  
  26. 101     pr_debug("%s: Bound Device %s to Driver %s/n",  
  27. 102          drv->bus->name, dev->bus_id, drv->name);  
  28. 103     goto Done;  
  29. 104   
  30. 105  ProbeFailed:  
  31. 106     if (ret == -ENODEV || ret == -ENXIO) {  
  32. 107         /* Driver matched, but didn't support device 
  33. 108          * or device not found. 
  34. 109          * Not an error; keep going. 
  35. 110          */  
  36. 111         ret = 0;  
  37. 112     } else {  
  38. 113         /* driver matched but the probe failed */  
  39. 114         printk(KERN_WARNING  
  40. 115                "%s: probe of %s failed with error %d/n",  
  41. 116                drv->name, dev->bus_id, ret);  
  42. 117     }  
  43. 118  Done:  
  44. 119     return ret;  
  45. 120 }  
  

可以看出是先调用了总线的probe方法,接着调用了设备的probe方法。


总之一句话,probe函数作为driver的最基本的函数指针,一旦你的device和driver匹配(match,由总线(bus)来完成,匹配工作发生在device_register()和drvier_register()

的时候),probe函数就肯定会被调用,期间一般会完成device的初始化,注册中断等操作。

顺便讲下在内核中是怎么按照driver mode来实现整个系统的设备和驱动注册的。

在系统初始化阶段,会首先向内核注册各种常用的总线类型,比如pci, usb, spi, i2c, platform等等,当然你也可以自己发明一种总线类型注册上去。

这部分代码一般放在./arch/arm/mach-xxx/board-xxx.c中。

在此之后,会将系统的设备列表,基本上整个系统的device都在这里了,一一地注册进内核,就是调用device_regisger注册的过程。然后是对于各个device设备driver的注册。

这部分代码一般放在./drvier/下面。

大部分device和driver的匹配方式就是看名字是否相同,这部分属于总线分内的事情。

原创粉丝点击