最近研究 alsa-asoc子系統的時候,注釋掉了 wm9081_i2c_driver.of_match_table = of_match_ptr(wm9081_of_match)成員,但是發現 wm9081的驅動還是成功的probe了 表示很不解,devicetree機制不是應該比較 compatible 成員嗎??一臉的懵逼。然后又注釋掉了id_table成員發現驅動就probe不了,頓時感覺就更奇怪了,id_table 難道不是設備樹以前的機制嗎??而且id_table 不是要和i2c_client 匹配嗎?這個i2c_client 又在哪里??
1 static const struct i2c_device_id wm9081_i2c_id[] = { 2 { "wm9081", 0 }, 3 { } 4 }; 5 MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id); 6 7 #ifdef CONFIG_OF 8 static const struct of_device_id wm9081_of_match[] = { 9 {.compatible = "wolfson,wm9081"}, 10 {} 11 12 }; 13 MODULE_DEVICE_TABLE(of,wm9081_of_match); 14 15 #endif 16 static struct i2c_driver wm9081_i2c_driver = { 17 .driver = { 18 .name = "wm9081", 19 .owner = THIS_MODULE, 20 .of_match_table = of_match_ptr(wm9081_of_match), 21 }, 22 .probe = wm9081_i2c_probe, 23 .remove = wm9081_i2c_remove, 24 .id_table = wm9081_i2c_id, 25 };
於是我去i2c-core.c 看了match規則
1 static int i2c_device_match(struct device *dev, struct device_driver *drv) 2 { 3 struct i2c_client *client = i2c_verify_client(dev); 4 struct i2c_driver *driver; 5 6 if (!client) 7 return 0; 8 9 /* Attempt an OF style match */ 10 if (of_driver_match_device(dev, drv)) 11 return 1; 12 13 /* Then ACPI style match */ 14 if (acpi_driver_match_device(dev, drv)) 15 return 1; 16 17 driver = to_i2c_driver(drv); 18 /* match on an id table if there is one */ 19 if (driver->id_table){ 20 return i2c_match_id(driver->id_table, client) != NULL; 21 } 22 23 return 0; 24 }
在 if (of_driver_match_device(dev, drv)) 中加了打印 系統起來以后發現成功打印了。看了這個地方是match成功了 但是並沒有執行probe,於是猜測在match之后肯定還有別的操作,但是這個時候i2c_driver 肯定已經注冊到bus上了 那么肯定是 i2c_device的問題了。
在i2c控制器注冊的時候會找設備樹中將所有的i2c節點 注冊成i2c_client
of_i2c_register_devices(adap);
-->of_i2c_register_device
-->i2c_new_device
-->device_register
我們來看看 device_register 這個函數
1 int device_register(struct device *dev) 2 { 3 device_initialize(dev); 4 return device_add(dev); 5 }
接着往下走
1 int device_add(struct device *dev) 2 { 3 ... 4 5 bus_probe_device(dev); 6 ... 7 8 }
1 void bus_probe_device(struct device *dev) 2 { 3 struct bus_type *bus = dev->bus; 4 struct subsys_interface *sif; 5 int ret; 6 7 if (!bus) 8 return; 9 10 if (bus->p->drivers_autoprobe) { 11 ret = device_attach(dev); 12 WARN_ON(ret < 0); 13 } 14 15 mutex_lock(&bus->p->mutex); 16 list_for_each_entry(sif, &bus->p->interfaces, node) 17 if (sif->add_dev) 18 sif->add_dev(dev, sif); 19 mutex_unlock(&bus->p->mutex); 20 }
首先判斷 bus->p->drivers_autoprobe 是否至位 然后進入 device_attach 中
1 int device_attach(struct device *dev) 2 { 3 int ret = 0; 4 5 device_lock(dev); 6 if (dev->driver) { 7 if (klist_node_attached(&dev->p->knode_driver)) { 8 ret = 1; 9 goto out_unlock; 10 } 11 ret = device_bind_driver(dev); 12 if (ret == 0) 13 ret = 1; 14 else { 15 dev->driver = NULL; 16 ret = 0; 17 } 18 } else { 19 ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); 20 pm_request_idle(dev); 21 } 22 out_unlock: 23 device_unlock(dev); 24 return ret; 25 }
首先判斷dev是否已經有指定的driver如果有則調用device_bind_driver綁定如果沒有則進入 bus_for_each_drv
1 static int __device_attach(struct device_driver *drv, void *data) 2 { 3 struct device *dev = data; 4 5 if (!driver_match_device(drv, dev)) 6 return 0; 7 8 return driver_probe_device(drv, dev); 9 }
讓我們進入到driver_match_device中
1 static inline int driver_match_device(struct device_driver *drv, 2 struct device *dev) 3 { 4 return drv->bus->match ? drv->bus->match(dev, drv) : 1; 5 }
如果有drv->bus->match 則調用 不然返回1
當然如果bus上的match返回0則直接return表示match失敗,我們在這個地方是成功的所以接着往下走
1 int driver_probe_device(struct device_driver *drv, struct device *dev) 2 { 3 int ret = 0; 4 5 if (!device_is_registered(dev)) 6 return -ENODEV; 7 8 pr_debug("bus: '%s': %s: matched device %s with driver %s\n", 9 drv->bus->name, __func__, dev_name(dev), drv->name); 10 11 pm_runtime_barrier(dev); 12 ret = really_probe(dev, drv); 13 pm_request_idle(dev); 14 15 return ret; 16 }
進入到really_probe中
static int really_probe(struct device *dev, struct device_driver *drv) { int ret = 0; int local_trigger_count = atomic_read(&deferred_trigger_count); atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", drv->bus->name, __func__, drv->name, dev_name(dev)); WARN_ON(!list_empty(&dev->devres_head)); dev->driver = drv; /* If using pinctrl, bind pins now before probing */ ret = pinctrl_bind_pins(dev); if (ret) goto probe_failed; if (driver_sysfs_add(dev)) { printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); 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); if (ret) goto probe_failed; } driver_bound(dev); ret = 1; pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name); goto done; probe_failed: devres_release_all(dev); driver_sysfs_remove(dev); dev->driver = NULL; dev_set_drvdata(dev, NULL); if (ret == -EPROBE_DEFER) { /* Driver requested deferred probing */ dev_info(dev, "Driver %s requests probe deferral\n", drv->name); driver_deferred_probe_add(dev); /* Did a trigger occur while probing? Need to re-trigger if yes */ if (local_trigger_count != atomic_read(&deferred_trigger_count)) driver_deferred_probe_trigger(); } else if (ret != -ENODEV && ret != -ENXIO) { /* driver matched but the probe failed */ printk(KERN_WARNING "%s: probe of %s failed with error %d\n", drv->name, dev_name(dev), ret); } else { pr_debug("%s: probe of %s rejects match %d\n", drv->name, dev_name(dev), ret); } /* * Ignore errors returned by ->probe so that the next driver can try * its luck. */ ret = 0; done: atomic_dec(&probe_count); wake_up(&probe_waitqueue); return ret; }
由此可以看出來在執行bus->match操作以后還會執行bus->probe,然后才會調用drv->probe,最后執行driver_bound(dev)綁定設備和驅動,看來我的問題應該出在了bus->probe上面,於是來看一下i2c bus中的 probe操作
struct bus_type i2c_bus_type = { .name = "i2c", .match = i2c_device_match, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, }; EXPORT_SYMBOL_GPL(i2c_bus_type);
static int i2c_device_probe(struct device *dev) { ... driver = to_i2c_driver(dev->driver); if (!driver->probe || !driver->id_table) return -ENODEV; .... }
終於發現了問題。。driver->id_table 如果沒有則會直接return。所以自然不會執行i2c_driver 中的probe函數了
流程大概如下圖