4

我看到了一种情况,其中未在驱动程序中定义“struct of_device_id”,而是在为同一设备条目添加的设备树(dts)文件兼容字符串中。

以下是芯片的示例设备树条目。

&i2c1 {

    ...

    adv7ex: adv7ex@4a {
            compatible = "adv7ex";
            reg = <0x4a>;
    };

    ...

 };

以下是注册为 I2C 驱动程序的芯片驱动程序的示例代码片段。

static struct i2c_device_id adv7ex_id[] = {
    { "adv7ex", ADV7EX },
    { }
};
MODULE_DEVICE_TABLE(i2c, adv7ex_id);

static struct i2c_driver adv7ex_driver = {
    .driver = {
        .owner = THIS_MODULE,
        .name = "adv7ex",
    },
    .probe = adv7ex_probe,
    .remove = adv7ex_remove,
    .id_table = adv7ex_id,
};

module_i2c_driver(adv7ex_driver);

您能否帮助我了解在这种情况下设备与驱动程序的绑定是如何发生的,因为驱动程序中没有“of_device_id”结构定义。

4

3 回答 3

2

我有一个类似的案例,终于找到了解释:设备树 i2c 设备绑定中似乎有一个未记录的扭曲。

让我们看看 i2c_device_match() (i2c-core-base.c):

/* Attempt an OF style match */
if (i2c_of_match_device(drv->of_match_table, client))
    return 1;

在 i2c_of_match_device() (i2c-core-of.c) 中实际发生了什么?:

*i2c_of_match_device(const struct of_device_id *matches,
         struct i2c_client *client){ 
const struct of_device_id *match;

if (!(client && matches))
    return NULL;

match = of_match_device(matches, &client->dev);
if (match)
    return match;

return i2c_of_match_device_sysfs(matches, client); }

嗯,我们首先尝试使用兼容字段的 Open Firmware 样式匹配,但如果失败,我们仍然调用 i2c_of_match_device_sysfs()。它有什么作用?

i2c_of_match_device_sysfs(const struct of_device_id *matches,
              struct i2c_client *client) {
const char *name;

for (; matches->compatible[0]; matches++) {
    /*
     * Adding devices through the i2c sysfs interface provides us
     * a string to match which may be compatible with the device
     * tree compatible strings, however with no actual of_node the
     * of_match_device() will not match
     */
    if (sysfs_streq(client->name, matches->compatible))
        return matches;

    name = strchr(matches->compatible, ',');
    if (!name)
        name = matches->compatible;
    else
        name++;

    if (sysfs_streq(client->name, name))
        return matches;
}

return NULL; }

答对了!正如您在代码中看到的, i2c_of_match_device_sysfs() 将设备树中的兼容字符串与驱动程序i2c_device_id的名称字段进行比较。另外,如果compatible字段中有逗号,则会对逗号后面的部分进行匹配。

所以在你的情况下,设备树数据

compatible = "adv7ex"

“adv7ex”匹配

static struct i2c_device_id adv7ex_id[] = {
{ "adv7ex", ADV7EX },
{ } };
MODULE_DEVICE_TABLE(i2c, adv7ex_id);

即使您的兼容是“acme-inc,adv7ex”,就像设备树的推荐符号一样,它仍然会匹配。

于 2020-03-04T13:35:40.210 回答
1

实际上,加载驱动程序的不是内核,而是用户空间工具:

MODULE_DEVICE_TABLE(i2c, adv7ex_id);

此宏在最终编译的模块(即:.ko 文件)中添加特定符号名称,这些名称将由 depmod 工具解析,然后将在 module.alias 中添加对驱动程序的“引用”,最后您的驱动程序将由您的用户热插拔工具。

参考:https ://www.kernel.org/doc/ols/2001/hotplug.pdf第 5 节。

于 2017-04-09T15:04:42.343 回答
0

正如您在此处看到的,i2c_device_match()函数首先尝试按compatible字符串匹配设备(OF 样式,即设备树)。如果失败,它会尝试通过 id 表匹配设备。

于 2017-11-06T08:35:31.710 回答