内核版本:3.9.5

SPI核心层(平台无关)

SPI子系统初始化的第一步就是将SPI总线注册进内核,并且在/sys下创建一个spi_master的类,以后注册的从设备都将挂接在该总线下. 下列函数位于drivers/spi/spi.c中:

 static int __init spi_init(void)
{
int status; buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);/*初始化缓存*/
if (!buf) {
status = -ENOMEM;
goto err0;
} status = bus_register(&spi_bus_type);/*注册spi总线,此步骤之后就会在/sys/bus目录下生成spi子目录*/
if (status < )
goto err1; status = class_register(&spi_master_class);/*注册spi类,此步骤之后就会在/sys/class目录下生成spi_master子目录*/
if (status < )
goto err2;
return ; err2:
bus_unregister(&spi_bus_type);
err1:
kfree(buf);
buf = NULL;
err0:
return status;
} /* board_info is normally registered in arch_initcall(),
* but even essential drivers wait till later
*
* REVISIT only boardinfo really needs static linking. the rest (device and
* driver registration) _could_ be dynamically linked (modular) ... costs
* include needing to have boardinfo data structures be much more public.
*/
postcore_initcall(spi_init);

我们来看spi_bus_type的定义:

 /*和电源管理相关的结构*/
static const struct dev_pm_ops spi_pm = {
.suspend = spi_pm_suspend,
.resume = spi_pm_resume,
.freeze = spi_pm_freeze,
.thaw = spi_pm_thaw,
.poweroff = spi_pm_poweroff,
.restore = spi_pm_restore,
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
pm_generic_runtime_idle
)
}; struct bus_type spi_bus_type = {
.name = "spi",
.dev_attrs = spi_dev_attrs,
.match = spi_match_device,
.uevent = spi_uevent,
.pm = &spi_pm,/*和电源管理相关的一些函数的结构封装*/
};

来看看spi_match_device函数都做了什么:

 /* 名词解释of: OpenFirmware
* 调用层次spi_match_device-->of_driver_match_device-->of_match_device-->
* of_match_node
* 用于驱动程序检查platform_device是否在其支持列表里
*/
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);
const struct spi_driver *sdrv = to_spi_driver(drv); /* Attempt an OF style match */
/* 不匹配返回0;匹配返回非0,指向struct of_device_id类型的指针
* dev:需要查找的设备; drv:驱动程序结构体
*/
if (of_driver_match_device(dev, drv))
return ; /* Then try ACPI */
if (acpi_driver_match_device(dev, drv))
return ; /*在驱动查找设备ID,找到返回真,否则假*/
if (sdrv->id_table)
return !!spi_match_id(sdrv->id_table, spi); return strcmp(spi->modalias, drv->name) == ;/*比较设备别名和驱动名称,匹配返回真*/
}

这个函数比我还单纯,没有啥看的,但是其透露出的消息是重要的.这关系到spi_device和spi_driver的终身幸福,她们能不能彼此走在一起.
到这里,我觉得已经不可避免的要牵扯出控制器和驱动的注册了,这部分是平台相关的,留待下一节再讲.

SPI子系统分析之三:驱动模块的更多相关文章

  1. SPI子系统分析之四:驱动模块

    内核版本:3.9.5 SPI控制器层(平台相关) 上一节讲了SPI核心层的注册和匹配函数,它是平台无关的.正是在核心层抽象了SPI控制器层的相同部分然后提供了统一的API给SPI设备层来使用.我们这一 ...

  2. input子系统分析之三:驱动模块

    内核版本:3.9.5 本节将以even handler来分析设备的注册和打开的过程,分析之前不妨回顾一下上节介绍的数据结构. 结合前两节分析可知,input子系统分为3层,最上一层是event han ...

  3. SPI子系统分析之一:框架

    内核版本:3.9.5 SPI子系统概述: 一个SPI主控制器对应一条SPI总线,当然在系统中有唯一的总线编号. SPI总线上有两类设备: 其一是主控端,通常作为SOC系统的一个子模块出现,很多嵌入式M ...

  4. SPI子系统分析之二:数据结构【转】

    转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...

  5. SPI子系统分析之二:数据结构

    内核版本:3.9.5 spi_master struct spi_master用来描述一个SPI主控制器,我们一般不需要自己编写spi控制器驱动. /*结构体master代表一个SPI接口,或者叫一个 ...

  6. [国嵌攻略][159][SPI子系统]

    SPI 子系统架构 1.SPI core核心:用于连接SPI客户驱动和SPI主控制器驱动,并且提供了对应的注册和注销的接口. 2.SPI controller driver主控制器驱动:用来驱动SPI ...

  7. SPI子系统

    一.SPI子系统模型 三个组成部分: SPI核心:连通了SPI客户驱动.SPI主控制器驱动 SPI控制器驱动:驱动芯片中的SPI控制器 SPI的FLASH(客户驱动) 二.SPI控制器驱动分析 sta ...

  8. spi子系统之驱动SSD1306 OLED

    spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...

  9. Android多线程分析之三:Handler,Looper的实现

    Android多线程分析之三:Handler,Looper的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前文<Android多 ...

随机推荐

  1. PowerDesigner生成Oracle表名带有引号的解决方法

    PowerDesigner生成表名带有引号,如下: /*==============================================================*/ /* Tabl ...

  2. 《DSP using MATLAB》示例9.2

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  3. flask第十四篇——重定向

    我们都知道京东的url是www.jd.com,但是当你输入www.jingdong.com时候,你会发现地址自动跳转到了www.jd.com,这种技术手段就叫做重定向. 重定向分为永久重定向和临时重定 ...

  4. altium常用快捷键记录

    选中一个网络的点和线ctrl+h: 翻转器件的层 鼠标拖动+L: 镜像器件 鼠标拖动+x: 查看单一层shift+s: 隐藏/查看某些器件ctrl+d:

  5. python 时间日期处理

    refer to : http://www.wklken.me/posts/2015/03/03/python-base-datetime.html#datetime-string http://ww ...

  6. gradle 项目构建以及发布maven 私服&& docker 私服构建发布

    1. 项目结构   2. 代码说明 a. Dockerfile docker 构建的 FROM openjdk:8-jre-alpine WORKDIR /appdemo/ COPY build/di ...

  7. RK3288 usb 摄像头旋转

    系统:Android 5.1 下面实现了摄像头 180 度旋转,旋转角度只需修改 orientation. diff --git a/hardware/rockchip/camera/CameraHa ...

  8. JLink RTT Client代替printf(IAR测试OK)

    1.打开J-Link安装目录,确保SEGGER目录中有J-Link RTT Client,没有的话必须安装4.9以上版本: 2.打开SEGGER目录下软件SEGGER目录,硬件版本Hardware是8 ...

  9. golang的interface到其他类型的数据转换

    以string为例 package main import "fmt" func main() { var a interface{} var b string a = " ...

  10. advapi32.dll kernel32.dll 中的两套注册表API

    日前遇到一件事:WebBrowser中的网页会用到一个“大众”ActiveX控件,为了保证兼容性以及和其它程序互不干扰,我们采用这样一种方案: 1. 我们的软件会自带该控件: 2. 如果系统中已注册有 ...