浅析linux下sdio接口对sd卡硬件检测流程
static struct pxamci_platform_data luther_mci_platform_data = {
.detect_delay = 20,//检测到sd设备插入之后,延时detect_delay个tick之后,执行函数
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.init = luther
_mci_init,
.setpower = luther
_mci_setpower,
.exit = luther
_mci_exit,
};
在luther
_init()->
//luther
_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_CFG_PIN(GPIO8_GPIO_MMC_DETECT));
所以设置GPIO8作为sd卡插入的中断检测IO
//pxamci_probe()->该函数是和platform的设备匹配上之后,会立即调用的probe
//host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc); 将mmc作为devid的传递参数
//就是调用设备函数luther
_mci_platform_data->
luther
_mci_init()
//request_irq(cd_irq, luther
_detect_int,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,"MMC card detect", data);
//这样将中断注册到了物理硬件系统
当GPIO8检测到电平变化,将触发pxamci_detect_irq()中断处理函数,
该函数会继续调用mmc_detect_change()->mmc_schedule_delayed_work(&host->detect, delay);调度该host的自动检测函数
对于host->detect的初始化是这样完成的:
pxamci_probe()->mmc_alloc_host()申请平台SD单元对应的mmc_host结构体->
INIT_DELAYED_WORK(&host->detect, mmc_rescan)创建该平台SD单元对应的sdio设备插入
检测内核work_queue工作队列函数mmc_rescan->mmc_rescan()这是一个共用函数,如果有4个SD卡控制器在你的arm平台上,
那么4个SD控制器将分别对应4个mmc_host结构体,分别对应4个sdio设备插入检测内核work_queue工作队列,
但工作队列都将调用mmc_rescan()这1个函数,所以linux内核的面向对象的类共用机制做得很好->
使用mmc_alloc_host()函数申请的平台mmc_host结构体,没有对其分配bus总线指针,仅分配了它所属的parent,即这个mmc不属于某个bus,所以这个mmc_host对应的dev也不会从任何bus总线上分配到任何driver驱动,这也是应该的.
mmc_attach_sdio()->mmc_attach_bus(host, &mmc_sdio_ops);
mmc_sdio_init_card()->sdio_init_func()->sdio_alloc_func()->这样当detect到sdio设备之后,
将分配dev对应的sdio_func结构题,
调用sdio_read_func_cis()的cistpl_manfid()来填充sd卡的vendor,这样当wlan驱动probe的时候,
就会和wlan驱动的id表中的vendor尝试匹配,如果成功,那么wlan驱动将接管该检测到的sd卡[gliethttp_20080626].