谁在驱动程序代码中调用“probe”函数?

我试图了解mcspi的omap2pandas板的驱动程序代码。

我不明白谁调用probe函数以及此驱动程序代码中的调用链是什么?

连接设备时如何通知驱动程序?

来自spi-omap2-mcspi.c的探测函数保存在static struct platform_driver omap2_mcspi_driver ,该函数在module_platform_driver(omap2_mcspi_driver);注册module_platform_driver(omap2_mcspi_driver); (在文件的末尾)。 platform_device.h中定义的module_platform_driver宏将把结构传递给来自drivers / base / platform.c的 platform_driver_register宏和__platform_driver_register函数。

 527 /** 528 * __platform_driver_register - register a driver for platform-level devices 529 * @drv: platform driver structure 530 * @owner: owning module/driver 531 */ 532 int __platform_driver_register(struct platform_driver *drv, 533 struct module *owner) 534 { ... 536 drv->driver.bus = &platform_bus_type; 537 if (drv->probe) 538 drv->driver.probe = platform_drv_probe; ... 544 return driver_register(&drv->driver); 545 } 546 EXPORT_SYMBOL_GPL(__platform_driver_register); 

探针现在从drivers / base / driver.c传递给driver_register函数

 139 /** 140 * driver_register - register driver with bus 141 * @drv: driver to register 142 * 143 * We pass off most of the work to the bus_add_driver() call, 144 * since most of the things we have to do deal with the bus 145 * structures. 146 */ 147 int driver_register(struct device_driver *drv) 148 { ... 154 if ((drv->bus->probe && drv->probe) || ... 167 ret = bus_add_driver(drv); ... 178 } 

所以,现在驱动程序已在总线中注册( platform_bus_type )。

实际的探测调用是通过driver_probe_device drivers / base / dd.c ,然后是really_probe (同一文件行265)完成的:

 265 static int really_probe(struct device *dev, struct device_driver *drv) 266 { ... 270 pr_debug("bus: '%s': %s: probing driver %s with device %s\n", 271 drv->bus->name, __func__, drv->name, dev_name(dev)); ... 287 if (dev->bus->probe) { 288 ret = dev->bus->probe(dev); /// <<<< HERE 289 if (ret) 290 goto probe_failed; 291 } else if (drv->probe) { 292 ret = drv->probe(dev); /// <<<< OR HERE 293 if (ret) 294 goto probe_failed; 295 } 296 297 driver_bound(dev); 298 ret = 1; 299 pr_debug("bus: '%s': %s: bound device %s to driver %s\n", 300 drv->bus->name, __func__, dev_name(dev), drv->name); 301 goto done;