接着上一节分析,上一节讲到,把
device_add(&pdev->dev);//把该设备注册到设备驱动模型中,接着该函数继续分析,看下设备驱动是怎么回事,设备是如何与驱动匹配绑定的。
int device_add(struct device *dev)
{
if (!dev->p) {//如果dev的私有数据为空,则继续相应的初始化
error = device_private_init(dev);
}
error = bus_add_device(dev);//把设备增加到设备依附的总线bus的devices链表上
bus_probe_device(dev);//设备探测总线上的驱动
}
void bus_probe_device(struct device *dev)
{
if (bus && bus->p->drivers_autoprobe) {//如果bus不为空,并且是自动探测,则device_attach.
ret = device_attach(dev);
}
}
int device_attach(struct device *dev)
{
int ret = 0;
device_lock(dev);
if (dev->driver) {//如果该device的driver不为空的话,就把该dev和该driver绑定,也就是把dev加到driver的devices链表
} else {
ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);//否则,用改dev去探测bus上的每一个驱动
}
}
下面是探测的过程,针对dev和从总线上取到的每一个驱动做匹配,匹配的过程如下:
static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
if (!driver_match_device(drv, dev))//调用总线的match函数,去匹配该dev和driver
return 0;
return driver_probe_device(drv, dev);//探测成功,试图绑定device和driver
}
下面就看下,总线的match函数
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* match against the id table first */
if (pdrv->id_table)//如果pdrv->id_table不为空,则用pdev的名字和该id_table列表中的名字匹配
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);//如果pdrv->id_table为空,则用pdev的名字和该drv的名字比较,看是否匹配
}
下面接着分析driver_probe_device(drv, dev);函数。
该函数调用int driver_probe_device(struct device_driver *drv, struct device *dev)
{
ret = really_probe(dev, drv);
}
really_probe()函数如下
static int really_probe(struct device *dev, struct device_driver *drv)
{
dev->driver = drv;//把drv赋值给dev的driver
if (dev->bus->probe) {//如果总线的probe函数存在,则先调用总线的probe函数
ret = dev->bus->probe(dev);
} else if (drv->probe) {//否则调用驱动的probe函数
ret = drv->probe(dev);
}
driver_bound(dev);//如果都探测通过,就把dev加入到该driver的device链表中
ret = 1;
}
到此平台设备已经加入到总线上,并且找到了自己的驱动。