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

Linux下设备与驱动match过程

程序员文章站 2022-07-13 21:44:49
...

在之前的学习过程中,我们知道了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,[email protected] {
			compatible = "qcom,qpnp-haptic";
			reg = <0xc000 0x100>;//device address

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

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

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

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

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

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