platform总线的匹配方式

总线的匹配方式
Linux系统内核使用结构体表示总线,定义在件/linux/bus.h中
1 struct bus_type {2 const char *name; /* 总线名字 */3 const char *dev_name; 4 struct device *dev_root;5 struct device_attribute *dev_attrs;6 const struct attribute_group **bus_groups; /* 总线属性 */7 const struct attribute_group **dev_groups; /* 设备属性 */8 const struct attribute_group **drv_groups; /* 驱动属性 */9 10 int (*match)(struct device *dev, struct device_driver *drv);11 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);12 int (*probe)(struct device *dev);13 int (*remove)(struct device *dev);14 void (*shutdown)(struct device *dev);15 16 int (*online)(struct device *dev);17 int (*offline)(struct device *dev);18 int (*suspend)(struct device *dev, pm_message_t state);19 int (*resume)(struct device *dev);20 const struct dev_pm_ops *pm;21 const struct iommu_ops *iommu_ops;22 struct subsys_private *p;23 struct lock_class_key lock_key;24 };
总线使用 match 函数来根据注册的设备来查找对应的驱动,或者根据注册的驱动来查找相应的设备,因此每一条总线都必须实现此函数 。match 函数有两个参数:dev 和 drv,这两个参数分别为和类型,也就是设备和驱动 。
总线是的一个具体实例,定义在文件 /base/.c,总线定义如下:
1 struct bus_type platform_bus_type = {2 .name = "platform",3 .dev_groups = platform_dev_groups,4 .match = platform_match,5 .uevent = platform_uevent,6 .pm = &platform_dev_pm_ops,7 };
就是平台总线,其中就是匹配函数
【platform总线的匹配方式】1 static int platform_match(struct device *dev,struct device_driver *drv)2 {3struct platform_device *pdev = to_platform_device(dev);4struct platform_driver *pdrv = to_platform_driver(drv);5 6/*When driver_override is set,only bind to the matching driver*/7if (pdev->driver_override)8return !strcmp(pdev->driver_override, drv->name);9 10/* Attempt an OF style match first */11if (of_driver_match_device(dev, drv))12return 1;1314/* Then try ACPI style match */15if (acpi_driver_match_device(dev, drv))16return 1;1718/* Then try to match against the id table */19if (pdrv->id_table)20return platform_match_id(pdrv->id_table, pdev) != NULL;2122/* fall-back to driver name match */23return (strcmp(pdev->name, drv->name) == 0);24 }
如上函数所示,驱动和设备的匹配有四种方法:
第 11~12 行,第一种匹配方式,OF 类型的匹配,ce 函数定义在文件/linux/.h 中 。结构体(表示设备驱动)中有个名为的成员变量,此成员变量保存着驱动的匹配表,设备树中的每个设备节点的属性会和表中的所有成员比较,查看是否有相同的条目,如果有的话就表示设备和此驱动匹配,设备和驱动匹配成功以后 probe 函数就会执行 。
第 15~16 行,第二种匹配方式,ACPI 匹配方式 。
第 19~20 行,第三种匹配方式,匹配,每个结构体有一个 成员变量,顾名思义,保存了很多 id 信息 。这些 id 信息存放着这个驱动所支持的驱动类型 。
第 23 行,第四种匹配方式,如果第三种匹配方式的不存在的话就直接比较驱动和设备的 name 字段,看看是不是相等,如果相等的话就匹配成功
对于支持设备树的 Linux 版本号,一般设备驱动为了兼容性都支持设备树和无设备树两种匹配式 。也就是第一种匹配方式一般都会存在,第三种和第四种只要存在一种就可以,一般用的最多的还是第四种,也就是直接比较驱动和设备的 name 字段 。
驱动
结 构 体 表 示驱动,
1 struct platform_driver {2int (*probe)(struct platform_device *);3int (*remove)(struct platform_device *);4void (*shutdown)(struct platform_device *);5int (*suspend)(struct platform_device *, pm_message_t state);6int (*resume)(struct platform_device *);7struct device_driver driver;8const struct platform_device_id *id_table;9bool prevent_deferred_probe;10 };