- 论坛徽章:
- 0
|
下面是对QualComm 8x50 上MMC host controller 驱动的初始化流程分析.
分析基于kernel 2.6.29 版本 (主要的代码为 driver/mmc/msm_sdcc.c 和 msm_sdcc.h 以及 arch 下的代码)
1. MMC 中涉及的总线类型
MMC 目录中的代码主要涉及到三种总线, 一种是platform bus, MMC host controller 作为一种platform device, 它是需要注册到platform bus上的。
另外两种是MMC自己创建的两种bus类型, 一种是 mmc bus type, 另一种是 sdio bus type. 它们是在mmc_init()中被创建的.通过调用 mmc_register_bus() 来注册 MMC 总线, 通过调用sdio_register_bus() 来注册 SDIO 总线.
当然 mmc bus 和 sdio bus 在 MMC host controller driver 的初始化中并没有被用到.
1.1 platform bus
the definition is in driver/base/platform.c
struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, .pm = PLATFORM_PM_OPS_PTR,};
1.2 mmc bus type
static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, .match = mmc_bus_match, .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, .suspend = mmc_bus_suspend, .resume = mmc_bus_resume,};1.3 sdio bus type
static struct bus_type sdio_bus_type = { .name = "sdio", .dev_attrs = sdio_dev_attrs, .match = sdio_bus_match, .uevent = sdio_bus_uevent, .probe = sdio_bus_probe, .remove = sdio_bus_remove,};
对于platform bus上的设备,通常初始化的流程是:
a. 在 platform bus上注册 platform device.
b. 在 platform bus上注册 platform driver.
c. 如果 platform bus 上的 device 和 driver 相互匹配, 则调用其 probe() 函数进行初始化.
对于SD host controller 设备也是一样.
2. MMC host controller device 的注册
MMC host controller 的硬件是嵌入在整个ap的芯片中的.因此如果在kernel中使能该MMC host controller 的配置,则在kernel的初始化中, MMC host controller device 将被注册.
在arch/arm/mach-xxx/.c, 比如Qualcomm 的8x50,对应的文件是 board-qsd8x50.c, 设备的注册流程如下:
qsd8x50_init() -> qsd8x50_init_mmc() -> msm_add_sdcc() -> platform_device_register() 从而将其注册的platform bus上.
注册的device数据结构如下,它定义了该设备的一些资源.比如 MEM, IRQ, DMA.
struct platform_device msm_device_sdc1 = { .name = "msm_sdcc", .id = 1, .num_resources = ARRAY_SIZE(resources_sdc1), .resource = resources_sdc1, .dev = { .coherent_dma_mask = 0xffffffff, },};
3. MMC host controller driver 的注册
在 driver/mmc/host/msm_sdcc.c 文件中,
msmsdcc_init() -> platform_driver_register() 从而将其注册到 platform bus 上.
static struct platform_driver msmsdcc_driver = { .probe = msmsdcc_probe, .remove = msmsdcc_remove, .suspend = msmsdcc_suspend, .resume = msmsdcc_resume, .driver = { .name = "msm_sdcc", },};
platform_driver_register 的调用流程如下:
platform_driver_register()driver_register()bus_add_driver()driver_attach()bus_for_each_dev()__driver_attach()driver_probe_device()
在driver_probe_device()函数,它将调用总线的match函数。如果match的话,它将调用really_probe函数,在该函数中,将真正调用bus和driver的probe函数。
4. probe() 函数
在 MMC host controller driver 中的 probe() 函数为 msmsdcc_probe(). 它的处理流程如下.
a. get resource.b. setup msm sdcc host structure.c. setup DMA.d. setup main peripheral bus clock.e. setup SDC MMC clock.f. setup MMC hsot structure.g. setup card detect change.h. setup a command timer.
总体来说, 就是初始化相关的数据结构, 并进行一些初始化设置.
下图是一个MMC中主要数据结构的关系图, probe() 函数主要是初始化 msmsdcc_host 和 mmc_host 数据结构,
d:/mmc-data.gif
5. MMC host controller driver 的对外接口
5.1 对上层的接口
msmsdcc_ops()
msmsdcc_status_notify_cb()
5.2 三个中断处理函数
msmsdcc_platform_status_irq()
msmsdcc_pio_irq()
msmsdcc_irq()
5.3 一个定时器
msmsdcc_command_expired
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/103613/showart_2056813.html |
|