linux SPI驱动代码追踪

一、Linux SPI 框架概述

linux系统下的spi驱动程序从逻辑上可以分为3个部分:

SPI Core:SPI Core 是 Linux 内核用来维护和管理 spi 的核心部分,SPI Core 提供操作接口,允许一个 spi master,spi driver 和 spi device 在 SPI Core 中进行注册、注销。

SPI Master Driver:SPI Master针对不同类型的spi控制器硬件,实现spi总线的硬件访问操作。SPI Master通过接口函数向SPI Core注册一个控制器。

SPI Device Driver:SPI Driver是对应于spi设备端的驱动程序,通过接口函数向SPI Core进行注册,SPI Driver的作用是将spi设备挂接到spi总线上;


二、代码追踪


1、注册SPI board_info

从内核启动开始
Linux从上电起执行完汇编代码阶段之后,就跳入main.c文件中,开始执行 start_kernel,一些系统外设的初始化设定、注册总线等等众多的初始化工作都在这里完成的。
在这里重点提及下面的几个函数的执行顺序以及它们完成的主要工作。

setup_arch() 函数
这里的函数流程主要是取出在 arch.info.init 段中MACHINE_START所定义的函数指针。这里其中有 .init_machine = smdkc110_machine_init 被赋予 void (*init_machine)(void) __initdata 这个函数指针,做好这些赋值工作之后,以便于后面的函数进行扫描arch.info.init 段中对应的函数以及进行执行它们。


reset_init() 函数
reset_init() 函数是 start_kernel() 函数中最后执行的一个函数,它的功能是创建一个内核线程,然后逐条取出 arch.info.init 段中的函数指针,执行对应的初始化函数。
在这里注意初始化顺序,setup.c中,宏定义 arch_initcall(customize_machine);规定了它的执行顺序是3,即:(arch_initcall(fn) __define_initcall(“3”,fn,3)


spi_register_board_info() 函数
spi_register_board_info() 函数为给定的板子注册SPI设备(片上spi资源)。
它在 smdkc110_machine_init() 函数中执行,而smdkc110_machine_init() 在宏定义 MACCHINA_START中赋值给 .init_machine成员,在上面的 setup_arch() 函数中 又赋值给void (*init_machine)(void) __initdata 这个函数指针,最后通过 reset_init() 函数去执行。

上面所有的过程,都为了一个结果,就是把 spi_board_info 注册到链表 board_list上。spi_device 封装了一个 spi_master 结构体,spi_master 的注册会在spi_register_board_info 之后,spi_master 注册的过程中会调用 scan_boardinfo 扫描board_list,找到挂接在它上面的spi设备,然后创建并注册spi_device。


2、注册 SPI 总线

SPI 总线注册流程如下图。触发这个流程的关键是宏定义 :postcore_initcall(spi_init)。

#define postcore_initcall(fn) __define_initcall(“2”,fn,2)

这个宏在 reset_init() 函数中扫描 arch.info.init 段中被执行 可见它的执行顺序比较早,早于上面的 spi_register_board_info()的注册。流程如下:


3、注册SPI控制器

spi_master 是控制器驱动层,主要提供 transfer 函数,进行 spi 协议的收发。spi_master 基于 Platform 总线模型,注册 spi_master 时扫描一个链表进行注册设备。注册函数用module_init(s3c64xx_spi_init)。

spi_register_master() 函数
由于spi设备不能被spi总线动态扫描,所以spi子系统使用了另一种方法,就是通过spi_register_board_info 函数将spi设备静态得登记到系统中。最后在 scan_boardinfo 函数中根据这些保存的结构体创建 spi 设备,(spi_new_device)。

spi_register_master
  -->device_add
   -->scan_boardinfo
    -->list_for_each_entry
     -->spi_new_device








==============================================================

platform_driver_register
->driver_register
->bus_add_driver
->driver_attach
->__driver_attach
->
(1、match----driver_match_device总线回调函数match匹配dev&drv 
2、probe---driver_probe_device->really_probe->drv->probe(dev);)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值