Linux下设备与驱动match过程

在之前的学习过程中,我们知道了Linux 设备驱动总线架构,抽象硬件上设备都是挂载在总线BUS上的,所以,定义了各种总线结构体。这里用platform_bus_type为例

struct bus_type platform_bus_type = {
	.name		= "platform",
	.dev_groups	= platform_dev_groups,
	.match		= platform_match,
	.uevent		= platform_uevent,
	.pm		= &platform_dev_pm_ops,
};

由之前的文章可以找到driver 和device 在注册时,Linux系统会调用bus->match函数,对新register的设备和驱动进匹配,如果匹配成功,再回去走driver->probe()函数。

可以参考文章linux设备驱动程序注册过程详解(一)

108 static inline int driver_match_device(struct device_driver *drv,
109                       struct device *dev)
110 {
111     return drv->bus->match ? drv->bus->match(dev, drv) : 1;
112 }

match 过程

调用的驱动注册总线的下得match函数(函数指针,callback)

下面来看看match函数具体是根据什么条件,将驱动和设备正确匹配成功的。

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)
		return !strcmp(pdev->driver_override, drv->name);

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))///*通过驱动里定义了of_device_id项,则通过这一项来比对;*
		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_table项,则通过对比id_table来判断*/
       return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */return ( strcmp(pdev->name, drv->name) == 0); /*通过对比平台设备名字和平台驱动名字来判断*/}

一般都是匹配第一个条件

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()函数,在这个函数里,通过把device_driver的of_match_table(of_device_id结构体的数组)和device里的of_node(device_node结构体)进行匹配,匹配方式是分别比较两者的name、type、和compatible字符串,三者要同时相同(一般name、和type为空,只比较compatible字符串,比较compatible时,是比较整个字符串,不管字符串里的逗号的,直接compare整个字符串

static const struct of_device_id spmi_match_table[] = {
	{ .compatible = "qcom,qpnp-haptic", },
	{ },
};
在dts文件当中也是定义的
pm660_haptics: qcom,haptic@c000 {
			compatible = "qcom,qpnp-haptic";
			reg = <0xc000 0x100>;//device address

这里要求compatible属性必须要求一致,否则,就不能匹配成功。

2.一个驱动可以匹配多个设备

之前有说过驱动和设备的对应关系是一对一和一对多的,也就是驱动可以匹配多个设备。

也就有了主设备号代表驱动,从设备号对应具体设备。

这里也是根据of_device_id 的table数组表,可以添加多个驱动。

参考文章:https://blog.csdn.net/ruanjianruanjianruan/article/details/61622053


你可能感兴趣的:(Linux下设备与驱动match过程)