冷烟花
哎呀哎呀哎呀我的妈~蜗牛背着那重重的壳呀,一步一步地往上爬~

内核版本:3.9.5

SPI核心层(平台无关)

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

 1 static int __init spi_init(void)
 2 {
 3     int    status;
 4 
 5     buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);/*初始化缓存*/
 6     if (!buf) {
 7         status = -ENOMEM;
 8         goto err0;
 9     }
10 
11     status = bus_register(&spi_bus_type);/*注册spi总线,此步骤之后就会在/sys/bus目录下生成spi子目录*/
12     if (status < 0)
13         goto err1;
14 
15     status = class_register(&spi_master_class);/*注册spi类,此步骤之后就会在/sys/class目录下生成spi_master子目录*/
16     if (status < 0)
17         goto err2;
18     return 0;
19 
20 err2:
21     bus_unregister(&spi_bus_type);
22 err1:
23     kfree(buf);
24     buf = NULL;
25 err0:
26     return status;
27 }
28 
29 /* board_info is normally registered in arch_initcall(),
30  * but even essential drivers wait till later
31  *
32  * REVISIT only boardinfo really needs static linking. the rest (device and
33  * driver registration) _could_ be dynamically linked (modular) ... costs
34  * include needing to have boardinfo data structures be much more public.
35  */
36 postcore_initcall(spi_init);

我们来看spi_bus_type的定义:

 1 /*和电源管理相关的结构*/
 2 static const struct dev_pm_ops spi_pm = {
 3     .suspend = spi_pm_suspend,
 4     .resume = spi_pm_resume,
 5     .freeze = spi_pm_freeze,
 6     .thaw = spi_pm_thaw,
 7     .poweroff = spi_pm_poweroff,
 8     .restore = spi_pm_restore,
 9     SET_RUNTIME_PM_OPS(
10         pm_generic_runtime_suspend,
11         pm_generic_runtime_resume,
12         pm_generic_runtime_idle
13     )
14 };
15 
16 struct bus_type spi_bus_type = {
17     .name        = "spi",
18     .dev_attrs    = spi_dev_attrs,
19     .match        = spi_match_device,
20     .uevent        = spi_uevent,
21     .pm        = &spi_pm,/*和电源管理相关的一些函数的结构封装*/
22 };

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

 1 /* 名词解释of: OpenFirmware
 2  * 调用层次spi_match_device-->of_driver_match_device-->of_match_device-->
 3  * of_match_node
 4  * 用于驱动程序检查platform_device是否在其支持列表里
 5  */
 6 static int spi_match_device(struct device *dev, struct device_driver *drv)
 7 {
 8     const struct spi_device    *spi = to_spi_device(dev);
 9     const struct spi_driver    *sdrv = to_spi_driver(drv);
10 
11     /* Attempt an OF style match */
12     /* 不匹配返回0;匹配返回非0,指向struct of_device_id类型的指针
13      * dev:需要查找的设备; drv:驱动程序结构体
14      */
15     if (of_driver_match_device(dev, drv))
16         return 1;
17 
18     /* Then try ACPI */
19     if (acpi_driver_match_device(dev, drv))
20         return 1;
21 
22     /*在驱动查找设备ID,找到返回真,否则假*/
23     if (sdrv->id_table)
24         return !!spi_match_id(sdrv->id_table, spi);
25 
26     return strcmp(spi->modalias, drv->name) == 0;/*比较设备别名和驱动名称,匹配返回真*/
27 }

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

posted on 2013-07-01 15:17  冷烟花  阅读(2112)  评论(0编辑  收藏  举报