为了补充@Federico 的回答,它很好地描述了一般情况,平台设备可以使用四个东西(优先级)与平台驱动程序匹配。这是平台“总线”的匹配功能:
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);
}
这里有两个重要的。
OF风格搭配
使用设备树 ( ) 进行匹配of_driver_match_device
。如果您还不了解设备树的概念,请阅读它。在这种数据结构中,每个设备在代表系统的树中都有自己的节点。每个设备还有一个compatible
属性,它是一个字符串列表。如果任何平台驱动程序将其中一个compatible
字符串声明为受支持,则会有一个匹配项,并且将调用驱动程序的探测器。
这是一个节点的示例:
gpio0: gpio@44e07000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio1";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <1>;
reg = <0x44e07000 0x1000>;
interrupts = <96>;
};
这描述了一个 GPIO 控制器。它只有一个兼容的字符串,即ti,omap4-gpio
. 将探测任何声明相同兼容字符串的已注册平台驱动程序。这是它的驱动程序:
static const struct of_device_id omap_gpio_match[] = {
{
.compatible = "ti,omap4-gpio",
.data = &omap4_pdata,
},
{
.compatible = "ti,omap3-gpio",
.data = &omap3_pdata,
},
{
.compatible = "ti,omap2-gpio",
.data = &omap2_pdata,
},
{ },
};
MODULE_DEVICE_TABLE(of, omap_gpio_match);
static struct platform_driver omap_gpio_driver = {
.probe = omap_gpio_probe,
.driver = {
.name = "omap_gpio",
.pm = &gpio_pm_ops,
.of_match_table = of_match_ptr(omap_gpio_match),
},
};
该驱动程序能够驱动三种类型的 GPIO,包括前面提到的一种。
请注意,平台设备不会神奇地添加到平台总线。架构/板初始化将调用platform_device_add
or platform_add_devices
,在这种情况下,在 OF 函数的帮助下扫描树。
名称匹配
如果您查看platform_match
,您将看到匹配回退到名称匹配。在驱动程序名称和设备名称之间进行简单的字符串比较。这就是旧平台驱动程序的工作方式。他们中的一些人仍然这样做,就像这里的这个:
static struct platform_driver imx_ssi_driver = {
.probe = imx_ssi_probe,
.remove = imx_ssi_remove,
.driver = {
.name = "imx-ssi",
.owner = THIS_MODULE,
},
};
module_platform_driver(imx_ssi_driver);
同样,特定于板的初始化必须调用platform_device_add
或platform_add_devices
添加平台设备,在名称匹配的情况下,这些设备完全在 C 中静态创建(名称在 C 中给出,资源如 IRQ 和基地址等)。