platform总线匹配设备和驱动有两种方法

内核版本:Linux-3.10.46

platform的mach函数如下:

/**
 * 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总线匹配设备和驱动有两种方法:

一是通过platform_driver中的id_table,如果id_table不存在,则只是简单的比较设备中的name字段和驱动中的name字段是否相同。

后面一种方法呢,已经见过无数次了,这里也就不再举例了,这里主要是看前一种方法。例如s3c-fb.c:

static struct platform_device_id s3c_fb_driver_ids[] = {
	{
		.name		= "s3c-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_64xx,
	}, {
		.name		= "s5pc100-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_s5pc100,
	}, {
		.name		= "s5pv210-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_s5pv210,
	}, {
		.name		= "exynos4-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_exynos4,
	}, {
		.name		= "exynos5-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_exynos5,
	}, {
		.name		= "s3c2443-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_s3c2443,
	}, {
		.name		= "s5p64x0-fb",
		.driver_data	= (unsigned long)&s3c_fb_data_s5p64x0,
	},
	{},
};
上面就是platform_device_id,可以看到支持的不只一种,包括2410、2416等等。而Platform_driver定义如下:
static struct platform_driver s3c_fb_driver = {
	.probe		= s3c_fb_probe,
	.remove		= s3c_fb_remove,
	.id_table	= s3c_fb_driver_ids,
	.driver		= {
		.name	= "s3c-fb",
		.owner	= THIS_MODULE,
		.pm	= &s3cfb_pm_ops,
	},
};
Louis210的platfrom_device定义如下:
struct platform_device s3c_device_fb = {
	.name		= "s3c-fb",//作为平台设备的LCD设备名
	.id		= -1,
	.num_resources	= ARRAY_SIZE(s3c_fb_resource),//资源数量
	.resource	= s3c_fb_resource,
	.dev		= {
		.dma_mask		= &samsung_device_dma_mask,
		.coherent_dma_mask	= DMA_BIT_MASK(32),
	},
};
那么在匹配的时候,match函数会在驱动的id_table表里面查找同platform device的name字段是否相同,如果相同则返回true,否则返回false。那么通过id_table这种方式有什么好处呢,如果只是简单的比较name字段是否相同,那么一个驱动只能支持特定的一个设备,而如果通过id_table的方式呢,一个驱动可以支持很多个设备,而它们只是name字段不同而已。

猜你喜欢

转载自blog.csdn.net/jerrygou/article/details/81023620