LINUX MMC 子系统分析之六 MMC card添加流程分析

         原文再续,书接上回。本文我们进行mmc子系统中mmc card的添加与删除流程。针对iic设备、spi设备、rtc设备等非热插拔设备而言,我们一般在板级文件或者设备树中定义外设信息,完成外设的注册;但针对mmc card而言,其属于热插拔设备,不需要在板级文件或设备树中进行外设的注册,而由mmc子系统通过mmc card的rescan机制,实现mmc card的自动检测及注册机制。本篇主要即用来介绍mmc card的检测流程及mmc card的注册及注销机制。主要分为如下两部分:

一、mmc card rescan机制

二、mmc card探测及移除

 

 

一、Mmc card rescan机制

    我们知道mmc card是依附于mmc controller的,因此mmc card rescan机制主要是基于mmc host进行设计的;该rescan机制主要 是通过工作队列实现的,如下图为该机制的实现流程,主要说明如下:

  1. Mmc host子系统提供了延迟队列机制,在执行mmc_alloc_host、mmc_add_host后,则完成了mmc card rescan延迟工作队列及其处理接口的创建等操作;
  2. 若要触发mmc card rescan(即调度工作队列),则调用mmc_detect_change接口,即可触发mmc card rescan(即完成mmc_host->detect队列的调度);
  3. 延迟队列的处理函数为mmc_rescan,该函数实现mmc card的添加与移除操作。

 

 

Mmc card rescan的几种方式

 

在上一小节的介绍中,延迟工作队列的创建及处理函数的注册操作由mmc host子模块完成(mmc_alloc_host/mmc_add),无需驱动开发者关心;而延迟工作队列的调度则需要具体的mmc host驱动进行实现。而mmc card rescan的方式有如下几种:

  1. Mmc card是不可移除的(如emmc),则在mmc host初始化时设置mmc host为nonremovable(仅在mmc_add_host时,调用mmc_detect_change完成一次mmc rescan,此后不再执行mmc rescan操作);
  2. Mmc host支持mmc card detect功能(通过提供mmc detect中断,进行mmc card detect),此种情况在mmc card detect中断对应的中断处理接口中,调用mmc_detect_change接口,对延迟工作队列进行调度,从而调用接口mmc_rescan,完成一次mmc card的rescan;
  3. Mmc host不支持mmc card detect功能,针对此情形,可以设置mmc host为poll模式。针对此种模式,在mmc_add_host执行一次mmc rescan时,在mmc rescan的最后会执行延迟1s调度该延迟工作队列,从而完成每秒执行一次mmc rescan操作。

       以上即为mmc card rescan的几种模式,在进行mmc host驱动开发时,可以根据自己驱动的情形,选择相应的处理方式进行驱动开发。

 

 

二、mmc card探测及移除

        Mmc card的探测及移除由mmc_rescan完成(而mmc_rescan接口则由上述一中的mmc_detect_change调度),下面我们分析mmc_rescan,来说明mmc card的探测及移除

mmc_rescan接口分析

mmc_rescan接口实现mmc card rescan的操作,该接口的处理流程图如下:

  1. 若mmc host不支持mmc card的移除操作,则做相应的判断(非第一次执行,则直接退出);
  2. 针对已注册的mmc card,则执行一次detect(host->bus_ops->detect),移除已经离线的mmc card(这会触发mmc_card的release操作,即调用device_unregister将该mmc_card从mmc_bus上移除,这会触发mmc_card的release操作,即调用device_unregister将该mmc_card从mmc_bus上移除,而这即触发mmc_driver与mmc_card的解绑流程(详见上一篇分析文章),从而调用mmc_driver->remove接口,即将已注册的mmc block device进行注销。);
  3. 若mmc host支持get_cd接口,则调用其get_cd接口针对cd引脚值,判断mmc card是否在线;
  4. 针对每一个频率(400khz、300khz、200khz、100khz(若host->f_min大于400khz,则以host->f_min进行探测)),调用mmc_rescan_try_freq进行mmc card rescan操作。

 

 

 

mmc_rescan_try_freq接口

该接口的处理流程如上图所示,该接口实现的功能如下:

  1. 设置mmc host的总线带宽、总线模式(pushpull),并设置mmc host(从powerup->poweron);
  2. 若mmc host支持hw_reset,执行hw_reset;
  3. 向mmc card 发送MMC_GO_IDLE_STATE命令(让mmc卡进入idle状态,该命令为broadcast commnad without response);
  4. 执行mmc 设备的探测:
    1. 针对sdio 设备,则调用mmc_attach_sdio执行sdio设备的探测;
    2. 针对sd设备,则调用mmc_attach_sd执行sd设备的探测;
    3. 针对mmc设备,则调用mmc_attach_mmc执行mmc设备的探测

mmc_attach_sdio、mmc_attach_sd、mmc_attach_mmc则为具体设备的探测及绑定流程。下面我们以sd card为主,进行sd card探测及绑定流程说明:

 

mmc_attach_sd接口分析

 

mmc_attach_sd接口的主要处理流程如下图所示,其实现的主要功能如下:

  1. 发送send_op_cond(该指令为broadcast command with response);若没有响应,则说明card不在线,程序返回;
  2. 若card回复,则说明card在线,则调用mmc_sd_attach_bus_ops,设置mmc_host->bus_ops为mmc_sd_ops_unsafe/mmc_sd_ops;
  3. 调用mmc_sd_init_card,获取mmc card的csd、cid,并创建mmc_card,并对mmc card进行初始化(如是否只读等信息);
  4. 调用mmc_add_card,将该mmc_card注册至mmc_bus中,该接口会调用device_register将mmc_card注册至mmc_bus上,而这即触发mmc_driver与mmc_card的绑定流程(详见上一篇分析文章),从而调用mmc_driver->probe接口,即执行mmc block device的注册操作。

 

 

 

 

 

         以上即为本篇的主要内容,主要介绍了mmc card的rescan机制以及mmc card的探测及移除流程。本篇亦为mmc子系统的最后一篇文章,针对mmc 子系统而言,涉及总线-设备-驱动模型、块设备模型,实现了mmc card、mmc host、mmc driver的抽象。而针对mmc 子系统而言,其实现了mmc driver的实现、mmc block device的实现、mmc card的rescan机制,而驱动工程师只需要实现mmc host驱动即可,无需关注mmc driver、mmc block device实现以及mmc card的注册。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/104718117
今日推荐