设备模型中device 和driver probe的过程


最近研究 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函数了

流程大概如下图

 流程图


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM