使用驱动程序中没有兼容字符串的设备树的驱动程序绑定
Driver binding using device tree without compatible string in the driver
我看到一种情况,其中 "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" 结构定义。
实际上,加载驱动程序的不是内核,而是用户空间工具:
MODULE_DEVICE_TABLE(i2c, adv7ex_id);
这个宏在你最终编译的模块(即:.ko 文件)中添加特定的符号名称,将由 depmod 工具解析,然后将 "reference" 添加到你的驱动程序中 module.alias最后,您的驱动程序将由您的用户热插拔工具加载。
如您所见here,i2c_device_match()
函数首先尝试通过compatible
字符串(OF 样式,即设备树)匹配设备。如果失败,它会尝试通过 id table.
匹配设备
我有一个类似的案例,终于找到了解释:
设备树 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); }
嗯,我们首先尝试使用兼容字段进行开放固件式匹配,但如果失败,我们仍会调用 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() 将设备树中的 compatible 字符串与驱动程序的 name 字段进行比较i2c_device_id。
另外,如果compatible字段中有逗号,则会匹配逗号后面的部分。
所以在你的情况下,设备树数据
compatible = "adv7ex"
与 "adv7ex" 在
中匹配
static struct i2c_device_id adv7ex_id[] = {
{ "adv7ex", ADV7EX },
{ } };
MODULE_DEVICE_TABLE(i2c, adv7ex_id);
即使您的 compatible 是 "acme-inc,adv7ex",作为设备树的推荐符号,它仍然会被匹配。
我看到一种情况,其中 "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" 结构定义。
实际上,加载驱动程序的不是内核,而是用户空间工具:
MODULE_DEVICE_TABLE(i2c, adv7ex_id);
这个宏在你最终编译的模块(即:.ko 文件)中添加特定的符号名称,将由 depmod 工具解析,然后将 "reference" 添加到你的驱动程序中 module.alias最后,您的驱动程序将由您的用户热插拔工具加载。
如您所见here,i2c_device_match()
函数首先尝试通过compatible
字符串(OF 样式,即设备树)匹配设备。如果失败,它会尝试通过 id table.
我有一个类似的案例,终于找到了解释: 设备树 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); }
嗯,我们首先尝试使用兼容字段进行开放固件式匹配,但如果失败,我们仍会调用 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() 将设备树中的 compatible 字符串与驱动程序的 name 字段进行比较i2c_device_id。 另外,如果compatible字段中有逗号,则会匹配逗号后面的部分。
所以在你的情况下,设备树数据
compatible = "adv7ex"
与 "adv7ex" 在
中匹配static struct i2c_device_id adv7ex_id[] = {
{ "adv7ex", ADV7EX },
{ } };
MODULE_DEVICE_TABLE(i2c, adv7ex_id);
即使您的 compatible 是 "acme-inc,adv7ex",作为设备树的推荐符号,它仍然会被匹配。