天天看點

platform總線的probe函數調用

    我們知道,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-&gt;driver.bus = &amp;platform_bus_type;</code>

<code>    </code><code>if</code> <code>(drv-&gt;probe)</code>

<code>        </code><code>drv-&gt;driver.probe = platform_drv_probe;</code>

<code>    </code><code>if</code> <code>(drv-&gt;</code><code>remove</code><code>)</code>

<code>        </code><code>drv-&gt;driver.</code><code>remove</code> <code>= platform_drv_remove;</code>

<code>    </code><code>if</code> <code>(drv-&gt;shutdown)</code>

<code>        </code><code>drv-&gt;driver.shutdown = platform_drv_shutdown;</code>

<code>    </code><code>return</code> <code>driver_register(&amp;drv-&gt;driver);</code>

<code>}</code>

這個函數首先是對驅動進行填充,然後調用driver_register()函數,這個函數是向核心注冊驅動的函數,不同的總線最終都是調用這個函數向核心進行驅動的注冊。

driver_register(&amp;drv-&gt;driver);

    bus_add_driver(drv);

         driver_attach(drv);

            bus_for_each_dev(drv-&gt;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-&gt;parent)    </code><code>/* Needed for USB */</code>

<code>        </code><code>device_lock(dev-&gt;parent);</code>

<code>    </code><code>device_lock(dev);</code>

<code>    </code><code>if</code> <code>(!dev-&gt;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-&gt;parent)</code>

<code>        </code><code>device_unlock(dev-&gt;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-&gt;bus-&gt;probe) {</code>

<code>        </code><code>ret = dev-&gt;bus-&gt;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-&gt;probe) {</code>

<code>        </code><code>ret = drv-&gt;probe(dev);</code>

<code>    </code><code>}</code>

分析可知,在驅動和裝置比對成功後,首先會判斷總線的的probe指針是否為空,如果不為空,則執行總線的prboe函數,如果總線的prboe函數為空,則進一步判斷驅動的probe函數是否為空,如果不為空,則執行驅動的probe函數

本文轉自 菜鳥養成記 51CTO部落格,原文連結:http://blog.51cto.com/11674570/1952431