在"SDIO驱动(9)Host注册"中提到,一旦host设备注册成功,接下来会启动一次扫描好获取并管理挂在该host上的card。
如果是一张可以热插拔的card,当card插入/拔出时触发中断,同样也将启动扫描流程。
以中断触发为例:
/*
* ISR for the CardDetect Pin
*/
static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
{
struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
dbg(host, dbg_irq, "card detect\n");
mmc_detect_change(host->mmc, msecs_to_jiffies(500));
return IRQ_HANDLED;
}
中断到来,s3cmci_irq_cd函数运行,还记得dev_id是创建中断请求时传进来的,类型就是s3cmci_host:
static int __devinit s3cmci_probe(struct platform_device *pdev)
{
struct s3cmci_host *host;
if (request_irq(host->irq, s3cmci_irq, 0, DRIVER_NAME, host)) {}
}
mmc_detect_change是一个"为他人作嫁衣裳"的函数,它启动一个delayed_work:host->detect。还记得它的初始化?
struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
{
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
}
根据参数msecs_to_jiffies(500)-convert milliseconds to jiffies,它将在500毫秒后运行:
void mmc_rescan(struct work_struct *work)
{
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
struct mmc_host *host =
container_of(work, struct mmc_host, detect.work);
int i;
if (host->rescan_disable)
return;
mmc_bus_get(host);
/*
* if there is a _removable_ card registered, check whether it is