目录
[匹配顺序(platform_match )](#匹配顺序(platform_match ))
匹配入口
driver_match_device 实际调用platform_match
cpp
driver_match_device(drv, dev);
static inline int driver_match_device(struct device_driver *drv,
struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
匹配顺序(platform_match )
static struct platform_driver bcm2835_rng_driver = {
.driver = {
.name = "bcm2835-rng", 方式1 /方式5
.of_match_table = bcm2835_rng_of_match, 方式2 /方式3()
},
.probe = bcm2835_rng_probe,
.id_table = bcm2835_rng_devtype, 方式4
};
cpp
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* When driver_override is set, only bind to the matching driver */
if (pdev->driver_override) //方式1: 根据device_driver 的name
return !strcmp(pdev->driver_override, drv->name);
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv)) //方式2: 根据device_driver的of_match_table
return 1; 去匹配device_node的compatibale/type/name
/* Then try ACPI style match */
if (acpi_driver_match_device(dev, drv))//方式3: 根据 device_driver的drv->acpi_match_table, drv->of_match_table
return 1;
/* Then try to match against the id table */
if (pdrv->id_table) //方式4:根据platform_driver驱动的id_table(id->name 与pdev->name)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
//方式5: 根据device_driver的name
}
方式1:
说明:driver_override 主要用于调试驱动,强制指定一个驱动来绑定到这个设备
操作: 用户空间通过特定的接口(如 sysfs)来设置这个值
实例: echo "my_driver" > /sys/bus/platform/devices/my_device/driver_override
方式2(重点)
根据of_device_id 的 compatible, type, name顺序去匹配device_node的compatible, type, name
方式3
acpi 方式,暂略
方式4 (重点)
static struct platform_device_id bcm2835_rng_devtype[] = {
{ .name = "bcm2835-rng" },
{ .name = "bcm63xx-rng" },
{ /* sentinel */ }
};
struct platform_device_id {
char name[PLATFORM_NAME_SIZE];
kernel_ulong_t driver_data;
};
static const struct platform_device_id *platform_match_id(
const struct platform_device_id *id, struct platform_device *pdev)
{
while (id->name[0]) {
if (strcmp(pdev->name, id->name) == 0) {
pdev->id_entry = id; 填充platform_device 的id_entry
return id;
}
id++;
}
return NULL;
}
方式5:
strcmp(pdev->name, drv->name) == 0