/*platform总线,驱动,设备模型。 这是一种机制。这样会使得驱动编写方便,便于维护*/
/*platform总线是一种虚拟的总线。 其实platform总线也是当作设备*/
/*******************************platform总线******************************************************/
int __init platform_bus_init(void)
{
int error;
early_platform_cleanup();
/*注册一个设备, 名为platform*/
error = device_register(&platform_bus);
if (error)
return error;
/* 注册一个总线,总线类型为platform_bus_type */
error = bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
return error;
}
/*platform总线的名字*/
struct device platform_bus = {
.init_name = "platform",
};
/*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驱动******************************************************/
/*平台驱动注册*/
int platform_driver_register(struct platform_driver *drv)
{
return driver_register(&drv->driver);
}
int driver_register(struct device_driver *drv)
{
ret = bus_add_driver(drv);
}
//Add a driver to the bus.
int bus_add_driver(struct device_driver *drv)
{
driver_attach(drv);
}
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
//回调函数
static int __driver_attach(struct device *dev, void *data)
{
if (!driver_match_device(drv, dev))
return 0;
}
//用总线的match函数进行匹配
static inline int driver_match_device(struct device_driver *drv,
struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
//通过设备的名称和驱动的名称想匹配
static int platform_match(struct device *dev, struct device_driver *drv)
{
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
/*总结: 把新注册的plarform_drv放入drv链表中, 从platform_dev链表中依次取出每一个dev,用bus的match函数匹配。
而bus的match函数是通过匹配设备和驱动的name的。如果相互匹配,然后就调用drv的probe函数。
*/
/*******************************platform设备******************************************************/
//平台设备注册
int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
platform_device_add()->device_add()->bus_probe_device()->device_attach()->__device_attach()->driver_probe_device()->really_probe()
static int really_probe(struct device *dev, struct device_driver *drv)
{
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
}
/*总结: 当一个新的platform设备注册到platform总线时, 会把platform设备放入到platform_bus中的dev链表中。 然后与platform_driver中的链表一一比较。 如果匹配成功
则会调用platform_bus中probe函数。 其实和piatform驱动注册时的流程是一样的。
其实,platform总线, 设备, 驱动只是一种机制。 这种机制可以方便编程。
如果要编写基于platform总线设备驱动模型的驱动。 对于程序员来说只需要编写platform设备文件和platform驱动文件。
platform_dev文件中需要定义设备的资源等。
platform_drv文件中最主要的是编写probe函数。这个函数一般都是和硬件相关的操作在里面。
*/