設備模型中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