linux总线驱动框架分析

    linux的总线驱动模型主要可以分为三个部分:总线、设备、驱动。

   内核初始化会先调用platform_bus_init()初始化platform_bus总线,之后由_initcall的优先级顺序可知先初始化各种实际总线例如spi、i2c。之后注册platform_device到platform_bus上,然后注册platform_driver到platform_bus。

   早在linux引进devicetree之前设备信息都是存在内核arch目录下,引进devicetree以后设备信息由设备树描述(此举为了删除linux内核大量和平台设备相关的代码)内核初始化会扫描设备树文件将设备信息保存到设备链表,提供链表的头指针,在注册设备时调用of_xxx(操作设备树链表的api)来获得设备信息。注册platform_device会将设备绑定到platform_bus,之后会遍历platform_bus上是否有与之匹配的驱动程序(调用platform_bus_type的match函数进行匹配),如果存在,匹配成功调用驱动的probe对设备进行初始化的配置。

    注册platform_driver到platform_bus会遍历platform_bus上是否有与之匹配的设备(调用platform_bus_type的match函数进行匹配),如果存在,匹配成功调用驱动的probe对设备进行初始化的配置。如果平台设备本身是实际的总线例如spi、i2c等,此时在驱动程序中会注册总线设备到到相应的总线上,之后会遍历xxx_bus上是否与之匹配的驱动程序,如果有会执行驱动的probe进行初始化相关配置。

   下面以spi总线驱动为例子做一个详细讲解。

    spi驱动分为spi控制器驱动、spi设备驱动。

    spi控制器挂在linux的虚拟总线platform bus上,包括spi控制器设备和spi控制器的设备驱动,在内核代码里分别由结构体platform_device和platform_driver表示,内核初始化时先注册platform_device(spi控制器设备)到platform bus,此时会遍历总线上是否存在匹配的spi控制器驱动程序(根据兼容性、设备id、设备名),匹配成功会调用控制器驱动的probe对控制器进行相关的配置。之后会注册spi控制器驱动程序到platform bus上,此时会遍历总线上是否存在匹配的spi控制器设备(根据兼容性、设备id、设备名),匹配成功会调用控制器驱动的probe对控制器进行相关的配置。

    在spi控制器驱动的probe函数中会注册spi设备到spi bus(spi bus此时已经初始化),此时会遍历spi总线上是否有与之匹配的设备驱动程序,如果有,调用spi设备驱动的probe函数对spi设备进行配置。spi设备驱动注册到spi bus时也会同样去匹配是否有匹配的设备。

扩展:

    linux内核的sysfs子系统用来管理linux设备驱动模型,参考下图,看懂他,你会对linux内核的总线驱动框架有一个深入的理解。

linux总线驱动框架分析