我们知道,platform总线提供了设备和驱动的mach函数,当设备和驱动匹配完成后,就会执行驱动的probe函数,但是这个probe函数是如何被调用的呢。
probe函数在设备驱动注册最后收尾工作,当设备的device 和其对应的driver 在总线上完成配对之后,系统就调用platform设备的probe函数完成驱动注册最后工作。资源、中断调用函数以及其他相关工作。下面是probe被调用的一些程序流程。
1:从注册函数platform_driver_register()函数开始
1
2
3
4
5
6
7
8
9
10
11
12
|
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函数如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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()函数的部分代码如下
1
2
3
4
5
6
7
8
9
|
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函数