欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-29 09:11:56
...

内核版本: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))    //ACPI风格匹配
		return 1;

	/* Then try to match against the id table */
	if (pdrv->id_table)    //匹配ID表(device设备名是否出现在driver的ID表中)
		return platform_match_id(pdrv->id_table, pdev) != NULL;

	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0);//匹配设备名和驱动名
}

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

一是通过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字段不同而已。

相关标签: kernel