intdriver_register(struct device_driver *drv) { int ret; structdevice_driver *other;
if (!bus_is_registered(drv->bus)) { pr_err("Driver '%s' was unable to register with bus_type '%s' because the bus was not initialized.\n", drv->name, drv->bus->name); return -EINVAL; }
intdriver_attach(conststruct 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);
/* * 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 */ return0; } elseif (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. */ return0; } elseif (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. */ return0; } /* ret > 0 means positive match */
/* 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)) return1;
/* Then try ACPI style match */ if (acpi_driver_match_device(dev, drv)) return1;
/* 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有关了。
driver_probe_device
driver_probe_device函数定义如下
staticintdriver_probe_device(conststruct 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; }
这里我们只关心__driver_probe_device函数的调用。
__driver_probe_device
其实现如下:
staticint __driver_probe_device(conststruct device_driver *drv, struct device *dev) { int ret = 0; ... if (initcall_debug) ret = really_probe_debug(dev, drv); else ret = really_probe(dev, drv); ... }
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; }
... }
与probe有关的只有call_driver_probe.
call_driver_probe
call_driver_probe函数定义如下:
staticintcall_driver_probe(struct device *dev, conststruct device_driver *drv) { int ret = 0;
if (dev->bus->probe) ret = dev->bus->probe(dev); elseif (drv->probe) ret = drv->probe(dev);
switch (ret) { case0: 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; }