int bus_add_driver(struct device_driver *drv)
{
struct subsys_private *sp = bus_to_subsys(drv->bus);
...
if (sp->drivers_autoprobe) {
error = driver_attach(drv);
...
}
int driver_attach(const struct device_driver *drv)
{
/* The (void *) will be put back to const * in __driver_attach() */
return bus_for_each_dev(drv->bus, NULL, (void *)drv, __driver_attach);
}
EXPORT_SYMBOL_GPL(driver_attach);
static int __driver_attach(struct device *dev, void *data)
{
const struct device_driver *drv = data;
bool async = false;
int ret;
/*
* 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.
*/
ret = driver_match_device(drv, dev);
if (ret == 0) {
/* no match */
return 0;
} else if (ret == -EPROBE_DEFER) {
dev_dbg(dev, "Device match requests probe deferral\n");
dev->can_match = true;
driver_deferred_probe_add(dev);
/*
* Driver could not match with device, but may match with
* another device on the bus.
*/
return 0;
} else if (ret < 0) {
dev_dbg(dev, "Bus failed to match device: %d\n", ret);
/*
* Driver could not match with device, but may match with
* another device on the bus.
*/
return 0;
} /* ret > 0 means positive match */
...
__device_driver_lock(dev, dev->parent);
driver_probe_device(drv, dev);
__device_driver_unlock(dev, dev->parent);
return 0;
}
// 这里就是判断总线有没有实现自己的match函数,如果没有实现,默认返回1,也就是匹配成功。
static inline int driver_match_device(const struct device_driver *drv,
struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
// platform_bus的结构体是有实现自己的一套match函数的。
static int platform_match(struct device *dev, const struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* When driver_override is set, only bind to the matching driver */
if (pdev->driver_override)
return !strcmp(pdev->driver_override, drv->name);
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try ACPI style match */
if (acpi_driver_match_device(dev, drv))
return 1;
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
// 首先将通用的device和driver都转换成platform下的设备和驱动。
// 然后再进行匹配,如果匹配成功,则返回1。
// 回到__driver_attach函数中,最后调用了driver_probe_device函数。
// 看名字就知道这个函数应该就跟probe有关了。
static int driver_probe_device(const struct device_driver *drv, struct device *dev)
{
int trigger_count = atomic_read(&deferred_trigger_count);
int ret;
atomic_inc(&probe_count);
ret = __driver_probe_device(drv, dev);
if (ret == -EPROBE_DEFER || ret == EPROBE_DEFER) {
driver_deferred_probe_add(dev);
/*
* Did a trigger occur while probing? Need to re-trigger if yes
*/
if (trigger_count != atomic_read(&deferred_trigger_count) &&
!defer_all_probes)
driver_deferred_probe_trigger();
}
atomic_dec(&probe_count);
wake_up_all(&probe_waitqueue);
return ret;
}
static int __driver_probe_device(const struct device_driver *drv, struct device *dev)
{
int ret = 0;
...
if (initcall_debug)
ret = really_probe_debug(dev, drv);
else
ret = really_probe(dev, drv);
...
}
static int really_probe(struct device *dev, const struct device_driver *drv)
{
...
re_probe:
device_set_driver(dev, drv);
/* If using pinctrl, bind pins now before probing */
ret = pinctrl_bind_pins(dev); // 设置设备所需的引脚
if (ret)
goto pinctrl_bind_failed;
...
ret = call_driver_probe(dev, drv);
if (ret) {
/*
* If fw_devlink_best_effort is active (denoted by -EAGAIN), the
* device might actually probe properly once some of its missing
* suppliers have probed. So, treat this as if the driver
* returned -EPROBE_DEFER.
*/
if (link_ret == -EAGAIN)
ret = -EPROBE_DEFER;
/*
* Return probe errors as positive values so that the callers
* can distinguish them from other errors.
*/
ret = -ret;
goto probe_failed;
}
// call_driver_probe了
static int call_driver_probe(struct device *dev, const struct device_driver *drv)
{
int ret = 0;
if (dev->bus->probe)
ret = dev->bus->probe(dev);
else if (drv->probe)
ret = drv->probe(dev);
switch (ret) {
case 0:
break;
case -EPROBE_DEFER:
/* Driver requested deferred probing */
dev_dbg(dev, "Driver %s requests probe deferral\n", drv->name);
break;
case -ENODEV:
case -ENXIO:
dev_dbg(dev, "probe with driver %s rejects match %d\n",
drv->name, ret);
break;
default:
/* driver matched but the probe failed */
dev_err(dev, "probe with driver %s failed with error %d\n",
drv->name, ret);
break;
}
return ret;
}
...
}
// bus->probe也就是platform总线的probe
static int platform_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
int ret;
...
if (drv->probe) {
ret = drv->probe(dev);
}
...
}
// 整体调用过程
__platform_driver_register
=> driver_register
=> bus_add_driver
=> driver_attach
=> __driver_attach
=> driver_match_device => bus->match => platform_match
=> driver_probe_device
=> __driver_probe_device
=> really_probe
=> call_driver_probe
=> bus->probe => platform_probe
=> drv->probe
__platform_driver_register // 【起点】你写的驱动开始向内核报到
=> driver_register // 通用驱动注册,把你的驱动包成一个通用的 struct device_driver
=> bus_add_driver // 【找组织】把驱动挂到对应的总线上(这里是 platform_bus)
=> driver_attach // 【连连看】开始在总线上寻找匹配的硬件设备(device)
=> __driver_attach // 对总线上每一个还没驱动的设备,都调用一次这个函数试试
/* 第一关:相亲匹配 (Match) */
=> driver_match_device
=> bus->match => platform_match // 【对暗号】对比设备树 compatible 字符串或 ID
/* 第二关:准备上岗 (Probe) */
=> driver_probe_device // 匹配成功了!准备正式绑定设备和驱动
=> __driver_probe_device // 检查设备是否已经挂载、是否需要延迟加载 (Deferred Probe)
=> really_probe // 【动真格】这是内核确定要调用 Probe 的最后防线
=> call_driver_probe // 准备好环境变量和资源,正式发起调用
/* 第三关:总线中转 */
=> bus->probe => platform_probe // 【中间人】总线先做预处理(如电源管理、时钟启动)
/* 终点:你的代码 */
=> drv->probe // 【最终调用】跳进你写的那个 xxx_probe 函数,开始初始化硬件