probe()函数是什么时候被调用,设备和驱动是怎么联系起来的??
1 总线注册阶段:
内核启动初始化时,main.c文件中platform平台初始化的路径:
kernel_init()
-->do_basic_setup()
-->driver_init()
-->platform_bus_init()
-->bus_register(&platform_bus_type),注册了一条platform总线(虚拟总线)。
2 添加设备时:
设备注册的时候(对于展讯8830 设备的在kernel/arch/arm/mach-sc/Board_sp8830ec.c中的sc8830_init_machine()中有platform_add_devices(devices,ARRAY_SIZE(devices)))注册的。
其中devices是platform_device类型的数组。
platform_add_devices(devices,ARRAY_SIZE(devices))//这是bsp中添加所有的设备
--》 platform_device_register(devs[i]);//注册平台设备
---》platform_device_add(pdev);将平台设备加入到platform_bus中
---》device_add(&pdev->dev);,就这样把设备给挂到虚拟的总线上。
3 驱动注册时:
Platform_driver_register()//注册平台驱动
-->driver_register()
-->bus_add_driver()//添加驱动到总线
-->driver_attach()//为驱动寻找相应的设备
-->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//遍历设备总线寻找驱动
-----》__driver_attach()//通过match判断驱动和设备是否匹配,这里通过比较dev和drv中的设备名来判断,所以设备名需要唯一
-->driver_probe_device(drv, dev); // 驱动和设备绑定
从上面可以看出,platform机制最后还是调用了bus_register(), device_add() ,driver_register()这三个关键的函数。
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 (drv->bus->match && !drv->bus->match(dev, drv)) //通过match判断驱动和设备是否匹配,这里通过比较dev和drv中的设备名来判断,所以设备名需要唯一
return 0;
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev); // 驱动和设备绑定
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0;
}
driver_probe_device(drv, dev); ---》really_probe(dev, drv);
static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
drv->bus->name, __func__, drv->name, dev->bus_id);
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
__func__, dev->bus_id);
goto probe_failed;
}
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev); //这里才真正调用了驱动的probe
if (ret)
goto probe_failed;
}