初始化流程
15 Jul 2024
Read time: 1 minute(s)
MMC 子系统的初始化包括 MMC 块设备、MMC 子系统、MMC 控制器驱动、card 设备等几条线,初始化顺序:
- MMC 核心初始化
- MC 控制器驱动初始化完成后才会对 card 设备进行初始化
- MMC 块设备初始化没有严格的先后顺序
MMC 块设备驱动初始化
MMC 在使用中,会将其抽象成一个块设备挂载到通用块层当中,通过 module_init(mmc_blk_init) 完成注册和初始化的操作,主要步骤如下:
- 注册总线(bus_register)。
- 将块设备名 ”mmc” 和主设备注册到块层中(register_blkdev)。
- 将 driver 设备驱动注册到驱动模型中(mmc_register_driver)。
- 块设备的初始化及磁盘分区的注册(mmc_blk_probe)。
MMC 子系统核心初始化
MMC 子系统的核心层负责处理 block 下达的请求,其中关于 MMC 协议的逻辑主要在此实现,通过 subsys_initcall(mmc_init) 完成初始化,其步骤如下:
- MMC 类型总线注册(mmc_register_bus)。
- 为控制器设备注册一个类(mmc_register_host_class)。
- SDIO 类型总线类型注册(sdio_register_b)。
card 设备注册与初始化
MMC 驱动的访问对象为外设,在子系统中会将外设抽象成一个 card 设备,在每次探测外设的时候都会判断该设备是否需要被注册,所以 card 设备注册介绍分为探测时机和注册过程两部分:
- 探测时机:
- mmc 控制器启动时
- 热插拔时
- mmc 控制器从 suspend 转为 resume 时
- 上述三种情况均会进行一次探测,都会调用到函数 mmc_detect_change
- 注册过程:在探测时调用的函数 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) 实现,其主要步骤如下:
- 使能时钟(artinchip_mmc_clk_enable)。
- 初始化计时机制,该机制实现发送命令和数据传输的 timeout 机制(timer_setup)。
- 初始化保护锁(spin_lock_init)。
- 初始化 tasklet,在驱动中很多流程的处理会在 tasklet 中(tasklet_init)。
- 初始化 DMA(artinchip_mmc_init_dma)。
- 中断初始化和注册(devm_request_irq)。
- 注册具体的控制器(mmc_alloc_host + mmc_add_host)。
- 初始化具体控制器,包括接口函数、工作电压、传输能力等。