详解Linux2.6内核中基于platform机制的驱动模型 (经典) (11)

如果bus和driver同时具备probe方法,则优先调用总线的probe函数。否则调用device_driver的probe函数,此 probe 函数是经过各种类型的driver重载的函数,这就实现了利用基类的统一方法来实现不同的功能。对于platform_driver来说,其就是:

394static int platform_drv_probe(struct device *_dev)
 395{
 396        struct platform_driver *drv = to_platform_driver(_dev->driver);
 397        struct platform_device *dev = to_platform_device(_dev);
 398
 399        return drv->probe(dev);
 400}

然后调用特定platform_driver所定义的操作方法,这个是在定义某个platform_driver时静态指定的操作接口。

至此,platform_driver成功挂接到platform bus上了,并与特定的设备实现了绑定,并对设备进行了probe处理。


6    bus、device及driver三者之间的关系
在数据结构设计上,总线、设备及驱动三者相互关联。

platform device包含device,根据device可以获得相应的bus及driver。

设备添加到总线上后形成一个双向循环链表,根据总线可以获得其上挂接的所有device,进而获得了 platform device。根据device也可以获得驱动该总线上所有设备的相关driver。

platform driver包含driver,根据driver可以获得相应的bus,进而获得bus上所有的device,进一步获得platform device,根据name对driver与platform device进行匹配,匹配成功后将device与相应的driver关联起来,即实现了platform device和platform driver的关联。

匹配成功后调用driver的probe进而调用platform driver的probe,在probe里实现驱动特定的功能。

7    哪些适用于plarform驱动?
platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform device提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,这样拥有更好的可移植性。platform机制的本身使用并不复杂,由两 部分组成:platform_device和platfrom_driver。Platform driver通过platform bus获取platform_device。

通常情况下只要和内核本身运行依赖性不大的外围设备,相对独立的,拥有各自独立的资源(地址总线和IRQs),都可以用 platform_driver来管理,而timer,irq等小系统之内的设备则最好不用platfrom_driver机制。

platform_device最大的特定是CPU直接寻址设备的寄存器空间,即使对于其他总线设备,设备本身的寄存器无法通过CPU总线访问,但总线的controller仍然需要通过platform bus来管理。

总之,platfrom_driver的根本目的是为了统一管理系统的外设资源,为驱动程序提供统一的接口来访问系统资源,将驱动和资源分离,提高程序的可移植性。

8    基于platform总线的驱动开发流程
基于Platform总线的驱动开发流程如下:
•    定义初始化platform bus
•    定义各种platform devices
•    注册各种platform devices
•    定义相关platform driver
•    注册相关platform driver
•    操作相关设备

以S3C24xx平台为例,来简单讲述下platform驱动的实现流程。
8.1    初始化platform_bus
Platform总线的初始化是在platform_bus_init()完成的,代码如下:

  26struct device platform_bus = {
  27        .bus_id         = "platform",
  28};
  29EXPORT_SYMBOL_GPL(platform_bus);

621int __init platform_bus_init(void)
 622{
 623        int error;
 624
 625        error = device_register(&platform_bus);
 626        if (error)
 627                return error;
 628        error =  bus_register(&platform_bus_type);
 629        if (error)
 630                device_unregister(&platform_bus);
 631        return error;
 632}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjjds.html