平台总线匹配流程platform_match

版权声明:本文为博主原创文章,未经博主允许不得转载。
https://blog.csdn.net/huangweiqing80/article/details/82760547

platform_match函数源码

/**
 * platform_match - bind platform device to platform driver.
 * @dev: device.
 * @drv: driver.
 *
 * Platform device IDs are assumed to be encoded like this:
 * "<name><instance>", where <name> is a short description of the type of
 * device, like "pci" or "floppy", and <instance> is the enumerated
 * instance of the device, like '0' or '42'.  Driver IDs are simply
 * "<name>".  So, extract the <name> from the platform_device structure,
 * and compare it against the name of the driver. Return whether they match
 * or not.
 */
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);

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))
		return 1;

	/* Then try ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	/* Then try to match against the id table */
	if (pdrv->id_table)
		return platform_match_id(pdrv->id_table, pdev) != NULL;

	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0);
}

从match函数中可以看到,platform总线匹配设备和驱动有两种方法:

1.通过of_driver_match_device进行匹配

static inline int of_driver_match_device(struct device *dev,
					 const struct device_driver *drv)
{
	return of_match_device(drv->of_match_table, dev) != NULL;
}

of_driver_match_device这个函数最终调用到__of_match_node()函数,在这个函数里,通过把struct device_driver的of_match_table和struct device里的of_node(device_node结构体)进行匹配,匹配方式是分别比较两者的name、type、和compatible字符串,三者要同时相同(一般name、和type为空,只比较compatible字符串,比较compatible时,是比较整个字符串,不管字符串里的逗号的,直接compare整个字符串)。compatible是dts中定义的节点
现在内核解析dtb文件,然后创建platform设备时,大部分platform设备是没有名字的,我还纠结那它们怎么和驱动match,原来bus_type的match函数添加了of_driver_match_device()这个匹配方式。他们大部分是通过compatible这个属性匹配成功的(这个compatible也对应dts里的compatible字符串)。
追溯到底,是利用"compatible"来匹配的,即设备树加载之后,内核会自动把设备树节点转换成 platform_device这种格式,同时把名字放到of_node这个地方。

2.通过platform_match_id来进行匹配

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;
			return id;
		}
		id++;
	}
	return NULL;
}

可以看到匹配的是platform_driver->id_table->name和platform_device->name

3.匹配设备中的name字段和驱动中的name字段

匹配设备中的name字段和驱动中的name字段是否相同,即platform_driver->name和platform_device->name

return (strcmp(pdev->name, drv->name) == 0);

猜你喜欢

转载自blog.csdn.net/huangweiqing80/article/details/82760547