我们知道,platform总线提供了设备和驱动的mach函数,当设备和驱动匹配完成后,就会执行驱动的probe函数,但是这个probe函数是如何被调用的呢。
1:从注册函数platform_driver_register()函数开始
<code>int</code> <code>platform_driver_register(</code><code>struct</code> <code>platform_driver *drv)</code>
<code>{</code>
<code> </code><code>drv->driver.bus = &platform_bus_type;</code>
<code> </code><code>if</code> <code>(drv->probe)</code>
<code> </code><code>drv->driver.probe = platform_drv_probe;</code>
<code> </code><code>if</code> <code>(drv-></code><code>remove</code><code>)</code>
<code> </code><code>drv->driver.</code><code>remove</code> <code>= platform_drv_remove;</code>
<code> </code><code>if</code> <code>(drv->shutdown)</code>
<code> </code><code>drv->driver.shutdown = platform_drv_shutdown;</code>
<code> </code><code>return</code> <code>driver_register(&drv->driver);</code>
<code>}</code>
这个函数首先是对驱动进行填充,然后调用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函数如下
<code>static</code> <code>int</code> <code>__driver_attach(</code><code>struct</code> <code>device *dev, </code><code>void</code> <code>*data)</code>
<code> </code><code>struct</code> <code>device_driver *drv = data;</code>
<code> </code><code>/*</code>
<code> </code><code>* Lock device and try to bind to it. We drop the error</code>
<code> </code><code>* here and always return 0, because we need to keep trying</code>
<code> </code><code>* to bind to devices and some drivers will return an error</code>
<code> </code><code>* simply if it didn't support the device.</code>
<code> </code><code>*</code>
<code> </code><code>* driver_probe_device() will spit a warning if there</code>
<code> </code><code>* is an error.</code>
<code> </code><code>*/</code>
<code> </code><code>if</code> <code>(!driver_match_device(drv, dev))</code>
<code> </code><code>return</code> <code>0;</code>
<code> </code><code>if</code> <code>(dev->parent) </code><code>/* Needed for USB */</code>
<code> </code><code>device_lock(dev->parent);</code>
<code> </code><code>device_lock(dev);</code>
<code> </code><code>if</code> <code>(!dev->driver)</code>
<code> </code><code>driver_probe_device(drv, dev);</code>
<code> </code><code>device_unlock(dev);</code>
<code> </code><code>if</code> <code>(dev->parent)</code>
<code> </code><code>device_unlock(dev->parent);</code>
<code> </code><code>return</code> <code>0;</code>
分析可知,首先是调用driver_mach_device函数进行设备和驱动的匹配(这里应该根据具体的总线来调用相应的mach函数),如果匹配失败则直接return 0,如果匹配成功,则进行下一步,probe函数的调用,probe函数的调用通过driver_probe_device()函数来引出。调用层次如下
driver_probe_device(drv, dev);
really_probe(dev, drv);
really_probe()函数的部分代码如下
<code>if</code> <code>(dev->bus->probe) {</code>
<code> </code><code>ret = dev->bus->probe(dev);</code>
<code> </code><code>if</code> <code>(ret)</code>
<code> </code><code>goto</code> <code>probe_failed;</code>
<code> </code><code>} </code><code>else</code> <code>if</code> <code>(drv->probe) {</code>
<code> </code><code>ret = drv->probe(dev);</code>
<code> </code><code>}</code>
分析可知,在驱动和设备匹配成功后,首先会判断总线的的probe指针是否为空,如果不为空,则执行总线的prboe函数,如果总线的prboe函数为空,则进一步判断驱动的probe函数是否为空,如果不为空,则执行驱动的probe函数
本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1952431