Edit online

初始化流程

15 Jul 2024
Read time: 1 minute(s)

MMC 子系统的初始化包括 MMC 块设备、MMC 子系统、MMC 控制器驱动、card 设备等几条线,初始化顺序:

  1. MMC 核心初始化
  2. MC 控制器驱动初始化完成后才会对 card 设备进行初始化
  3. MMC 块设备初始化没有严格的先后顺序

MMC 块设备驱动初始化

MMC 在使用中,会将其抽象成一个块设备挂载到通用块层当中,通过 module_init(mmc_blk_init) 完成注册和初始化的操作,主要步骤如下:

  1. 注册总线(bus_register)。
  2. 将块设备名 ”mmc” 和主设备注册到块层中(register_blkdev)。
  3. 将 driver 设备驱动注册到驱动模型中(mmc_register_driver)。
  4. 块设备的初始化及磁盘分区的注册(mmc_blk_probe)。

MMC 子系统核心初始化

MMC 子系统的核心层负责处理 block 下达的请求,其中关于 MMC 协议的逻辑主要在此实现,通过 subsys_initcall(mmc_init) 完成初始化,其步骤如下:

  1. MMC 类型总线注册(mmc_register_bus)。
  2. 为控制器设备注册一个类(mmc_register_host_class)。
  3. SDIO 类型总线类型注册(sdio_register_b)。

card 设备注册与初始化

MMC 驱动的访问对象为外设,在子系统中会将外设抽象成一个 card 设备,在每次探测外设的时候都会判断该设备是否需要被注册,所以 card 设备注册介绍分为探测时机和注册过程两部分:

  1. 探测时机:
    • mmc 控制器启动时
    • 热插拔时
    • mmc 控制器从 suspend 转为 resume 时
    • 上述三种情况均会进行一次探测,都会调用到函数 mmc_detect_change
  2. 注册过程:
    在探测时调用的函数 mmc_detect_change,该函数会调用 card 设备的注册函数 mmc_rescan,以 SD 卡为例,其注册和初始化过程如下:
    • 判断当前卡是否被注册
    • 若卡已经注册,则确认卡是否存在,存在则提前跳出,若不存在则释放相关资源
    • 若卡未注册,则启动控制器进行卡的初始化步骤
    • 为控制器绑定具体总线的操作函数(mmc_attach_bus(host, &mmc_sd_ops))
    • 适配卡的工作电压(mmc_select_voltage)
    • 根据 MMC 协议初始化卡,使卡进入传输模式化(mmc_sd_init_card)
    • 注册卡设备(mmc_add_card)

控制器驱动注册与初始化

MMC 控制器驱动通过对控制器进行操作完成核心层的请求,控制器驱动也是实现和外设进行通信的软件最底层驱动,该层驱动根据厂商不同而不同,D211 的 SDMC 模块的控制器驱动通过 module_platform_driver(artinchip_mmc_aic_pltfm_driver) 实现,其主要步骤如下:

  1. 使能时钟(artinchip_mmc_clk_enable)。
  2. 初始化计时机制,该机制实现发送命令和数据传输的 timeout 机制(timer_setup)。
  3. 初始化保护锁(spin_lock_init)。
  4. 初始化 tasklet,在驱动中很多流程的处理会在 tasklet 中(tasklet_init)。
  5. 初始化 DMA(artinchip_mmc_init_dma)。
  6. 中断初始化和注册(devm_request_irq)。
  7. 注册具体的控制器(mmc_alloc_host + mmc_add_host)。
  8. 初始化具体控制器,包括接口函数、工作电压、传输能力等。