我們知道,platform總線提供了設備和驅動的mach函數,當設備和驅動匹配完成後,就會執行驅動的probe函數,但是這個probe函數是如何被調用的呢。
probe函數在設備驅動註冊最後收尾工作,當設備的device 和其對應的driver 在總線上完成配對之後,系統就調用platform設備的probe函數完成驅動註冊最後工作。資源、中斷調用函數以及其他相關工作。下面是probe被調用的一些程序流程。
1:從註冊函數platform_driver_register()函數開始
int platform_driver_register(struct platform_driver *drv) { drv->driver.bus = &platform_bus_type; if (drv->probe) drv->driver.probe = platform_drv_probe; if (drv->remove) drv->driver.remove = platform_drv_remove; if (drv->shutdown) drv->driver.shutdown = platform_drv_shutdown; return driver_register(&drv->driver); }
這個函數首先是對驅動進行填充,然後調用driver_register()函數,這個函數是向內核註冊驅動的函數,不同的總線最終都是調用這個函數向內核進行驅動的註冊。
driver_register(&drv->driver);
bus_add_driver(drv);
driver_attach(drv);
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
__driver_attach
__driver_attach函數如下
static int __driver_attach(struct device *dev, void *data) { struct device_driver *drv = data; /* * Lock device and try to bind to it. We drop the error * here and always return 0, because we need to keep trying * to bind to devices and some drivers will return an error * simply if it didn't support the device. * * driver_probe_device() will spit a warning if there * is an error. */ if (!driver_match_device(drv, dev)) return 0; if (dev->parent) /* Needed for USB */ device_lock(dev->parent); device_lock(dev); if (!dev->driver) driver_probe_device(drv, dev); device_unlock(dev); if (dev->parent) device_unlock(dev->parent); return 0; }
分析可知,首先是調用driver_mach_device函數進行設備和驅動的匹配(這裏應該根據具體的總線來調用相應的mach函數),如果匹配失敗則直接return 0,如果匹配成功,則進行下一步,probe函數的調用,probe函數的調用通過driver_probe_device()函數來引出。調用層次如下
driver_probe_device(drv, dev);
really_probe(dev, drv);
really_probe()函數的部分代碼如下
if (dev->bus->probe) { ret = dev->bus->probe(dev); if (ret) goto probe_failed; } else if (drv->probe) { ret = drv->probe(dev); if (ret) goto probe_failed; }
分析可知,在驅動和設備匹配成功後,首先會判斷總線的的probe指針是否爲空,如果不爲空,則執行總線的prboe函數,如果總線的prboe函數爲空,則進一步判斷驅動的probe函數是否爲空,如果不爲空,則執行驅動的probe函數