From abdeda5e09ec2b0d0944bbd1c9f470b08c504202 Mon Sep 17 00:00:00 2001 From: Chuanxiao Dong Date: Mon, 24 Oct 2011 13:01:52 +0800 Subject: [PATCH] mmc: SDHCI: fix the issue related with SD card insert/remove BZ 1605 insert/remove a SD card quickly while the card is inusing, can cause MMC driver print timeout error message. This is reasonable. But should not cause system getting slow. This patch will fix this. Change-Id: Iffb1fe615603f2cd5ab74d28120d38167d317cb7 Signed-off-by: Chuanxiao Dong Reviewed-on: http://android.intel.com:8080/23125 Reviewed-by: Gross, Mark Tested-by: Gross, Mark --- drivers/mmc/host/sdhci-pci.c | 17 ++++++++++++++++- drivers/mmc/host/sdhci.c | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 2706cd3..3be533c 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -196,12 +196,27 @@ static int mfd_emmc_gpio_parse(struct sfi_table_header *table) #ifdef CONFIG_PM_RUNTIME +/* + * MFLD SD card insert/remove handler + * When removing a SD card, there may be still requests + * transferring. But removing a SD card can cause MFLD + * host controller reset its power register automatically + * which causes host cannot generate interrupts for the + * current transferring requests. That will trigger timeout + * timer. + * So before start to detect a card, finish the current + * request first. + */ static irqreturn_t mfd_sd_cd(int irq, void *dev_id) { struct sdhci_pci_slot *slot = dev_id; struct sdhci_host *host = slot->host; - mmc_detect_change(host->mmc, msecs_to_jiffies(200)); + if (host->card_tasklet.func == NULL) + return IRQ_NONE; + + tasklet_schedule(&host->card_tasklet); + return IRQ_HANDLED; } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 012bac0..8c4c99d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1484,6 +1484,14 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) else present = sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT; + /* + * If user insert/remove card too quickly, host may send + * command before host power up. That is bad, which can + * lead host generate no interrupts. + * So before sending command, check power control register + */ + if (!(sdhci_readb(host, SDHCI_POWER_CONTROL) & SDHCI_POWER_ON)) + present = false; if (!present || host->flags & SDHCI_DEVICE_DEAD) { host->mrq->cmd->error = -ENOMEDIUM; -- 2.7.4