platform可以说是内核抽象出来的一条虚拟总线平台,内核开发者原意是想把硬件层次上的结构关系用软件抽象模拟出来,但是对一些硬件,这样做往往不太合适,例如对于片上soc,外围设备的控制器都集成在处理器上,如果过度的剥离抽象,会使得原本物理上紧密的结构而在软件上变成的偏于独立,因此有了platform,对于联系紧密的soc这往往再合适不过,另外对于从soc上直接引出的引脚,难于独立出来,都可以利用platform来表述。
有了前面关于bus,driver,device的理解,platform平台的理解就比较简单,都是以前面为原型进行的再次封装,好了下面就让我们以具体代码为例进行分析。
一、platform的初始化
platform的初始化代码位于driver/base目录下的platform.c
int __init platform_bus_init(void)
{
int error;
early_platform_cleanup(); // 清除platform设备链表
error = device_register(&platform_bus); //将平台bus作为一个设备注册,出现在device目录
if (error)
return error;
error = bus_register(&platform_bus_type); //注册平台类型的bus,将出现在bus目录下
if (error)
device_unregister(&platform_bus);
return error;
}
先 来看一下 early_platform_cleanup() 这个函数:
void __init early_platform_cleanup(void)
{
struct platform_device *pd, *pd2;
/* clean up the devres list used to chain devices */
/* 遍历early_platform_device_list,把连接到此的所有节点清0,
平台设备都会挂到该节点,现在是平台设备的初始化阶段,自然不
能有连接到此的设备 */
l ist_for_each_entry_safe(pd, pd2, &early_platform_device_list,
dev.devres_head) {
list_del(&pd->dev.devres_head);
memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
}
}
再来看一下另外两个结构体:
struct device platform_bus = {
.init_name = "platform",
};
以及
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
二、platform_device的注册
platform_device无疑是device的封装,先给出该结构具体代码: