内核已经存在SD卡的驱动,所以仅需要添加SD卡设备到设备列表注册就可以了。但是从头到尾分析一下MMC的驱动对于理解linux的驱动设计
思想是很有帮助的。mmc分为控制器和mmc卡,所以也有两个驱动
1. core文件夹的core.c先创建一个工作队列,再注册总线和类。
2. 接着card文件夹的block.c再申请主设备号,并将块设备的驱动挂载到上面的总线上(mmc_register_driver)。
3. host文件夹中sdhci-s3c.c再注册platform驱动,板文件注册platform设备,所以platform总线会调用该驱动的probe。
4. probe中主要先由板文件得到硬件资源,申请后记录到一个结构体中struct sdhci_s3c *sc;这个主要用来方便实现操作函数。
5. probe再申请控制器结构体host,并初始化一些成员,关键是指定了操作函数集合sdhci_s3c_ops。
其实sdhci_alloc_host分配了sdhci_host和mmc_host两个结构体,并将sdhci_host的mmc成员指向mmc_host。
6. probe再调用sdhci_add_host(host),实际上又调用了mmc_add_host将这个控制器设备添加到内核中。
7. 总结:
其实这个host设备和字符驱动中的cdev作用差不多,仅用platform_driver与设备匹配后再在cdev的fops中做真正的硬件工作。
所以这个添加的host也是做真正的工作:探测到mmc卡并初始化一个card结构体挂载到总线上。总线用最前面的块设备驱动来匹配,
最终肯定是用一个块设备来表示卡。那么块设备驱动中的函数是怎样调用到这个控制器host的函数呢?
很简单,仅需要用一个指针指向host就可以了。
还有,在platform_driver的probe中添加到内核的控制器设备host添加到哪里了?它又是如何完成上面的探测工作呢?
由下面,host仅需要探测卡和发送数据命令即可,工作简单,所以就放在/sys/class/mmc/下的mmc0文件。而不需要把控制器也
挂载到总线上,因为它不需要什么驱动,不像I2C控制器也挂载在总线上并要驱动。
探测工作主要依靠工作队列,中断,定时器来完成的,不需要深究。