From d9a820a163a95e1f66301ddf9e31198fd9938a62 Mon Sep 17 00:00:00 2001 From: lintao Date: Sat, 20 Sep 2014 16:59:44 +0800 Subject: [PATCH] mmc: schedule out rescan flow for confilicting with ehci reset Signed-off-by: lintao --- drivers/mmc/host/rk_sdmmc.c | 18 +++++++++++++++--- include/linux/mmc/rk_mmc.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/rk_sdmmc.c b/drivers/mmc/host/rk_sdmmc.c index 8ea7e838c8e8..57fd3ea65c30 100755 --- a/drivers/mmc/host/rk_sdmmc.c +++ b/drivers/mmc/host/rk_sdmmc.c @@ -3764,6 +3764,17 @@ static void dw_mci_dto_timeout(unsigned long host_data) enable_irq(host->irq); } + + +void resume_rescan_enable(struct work_struct *work) +{ + struct dw_mci *host = + container_of(work, struct dw_mci, resume_rescan.work); + host->mmc->rescan_disable = 0; + mmc_detect_change(host->mmc, 10); +} + + int dw_mci_probe(struct dw_mci *host) { const struct dw_mci_drv_data *drv_data = host->drv_data; @@ -3852,7 +3863,7 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); - + INIT_DELAYED_WORK(&host->resume_rescan, resume_rescan_enable); /* * Get the host data width - this assumes that HCON has been set with * the correct values. @@ -4010,6 +4021,7 @@ void dw_mci_remove(struct dw_mci *host) int i; del_timer_sync(&host->dto_timer); + cancel_delayed_work(&host->resume_rescan); mci_writel(host, RINTSTS, 0xFFFFFFFF); mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */ @@ -4102,7 +4114,7 @@ int dw_mci_resume(struct dw_mci *host) if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0) MMC_DBG_ERR_FUNC(host->mmc, "Default pinctrl setting failed! [%s]", mmc_hostname(host->mmc)); - host->mmc->rescan_disable = 0; + host->mmc->rescan_disable = 1; /* Disable jtag*/ if(cpu_is_rk3288()) grf_writel(((1 << 12) << 16) | (0 << 12), RK3288_GRF_SOC_CON0); @@ -4160,7 +4172,7 @@ int dw_mci_resume(struct dw_mci *host) dw_mci_setup_bus(slot, true); } } - + schedule_delayed_work(&host->resume_rescan, msecs_to_jiffies(2000)); return 0; } EXPORT_SYMBOL(dw_mci_resume); diff --git a/include/linux/mmc/rk_mmc.h b/include/linux/mmc/rk_mmc.h index d568335b3dd6..1a4bf4c75d37 100755 --- a/include/linux/mmc/rk_mmc.h +++ b/include/linux/mmc/rk_mmc.h @@ -141,6 +141,7 @@ struct dw_mci { unsigned int prev_blksz; unsigned char timing; struct workqueue_struct *card_workqueue; + struct delayed_work resume_rescan; /* DMA interface members*/ int use_dma; -- 2.34.1