diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 8ac039a..be11151 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -217,6 +217,8 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd /* Now we have a working card_detect again */ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; } + if (cpu_is_mx51()) + host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; return 0; diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9e15f41..11ef076 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -127,10 +127,14 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) return; - if (enable) + sdhci_mask_irqs(host, irqs); + if (enable) { + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) + irqs = SDHCI_INT_CARD_INSERT; + else + irqs = SDHCI_INT_CARD_REMOVE; sdhci_unmask_irqs(host, irqs); - else - sdhci_mask_irqs(host, irqs); + } } static void sdhci_enable_card_detection(struct sdhci_host *host) @@ -992,6 +996,9 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) u16 clk; unsigned long timeout; + if ((clock == 0) && (SDHCI_INT_CARD_INSERT & sdhci_readl(host, SDHCI_INT_ENABLE))) + goto out; + if (clock == host->clock) return; @@ -1001,6 +1008,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) return; } + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); if (clock == 0) @@ -1583,9 +1591,18 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) DBG("*** %s got interrupt: 0x%08x\n", mmc_hostname(host->mmc), intmask); - if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { - sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT | - SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS); + if (intmask & SDHCI_INT_CARD_INSERT) { + sdhci_unmask_irqs(host, SDHCI_INT_CARD_REMOVE); + sdhci_mask_irqs(host, SDHCI_INT_CARD_INSERT); + sdhci_writel(host, intmask & SDHCI_INT_CARD_INSERT, + SDHCI_INT_STATUS); + tasklet_schedule(&host->card_tasklet); + } + if (intmask & SDHCI_INT_CARD_REMOVE) { + sdhci_unmask_irqs(host, SDHCI_INT_CARD_INSERT); + sdhci_mask_irqs(host, SDHCI_INT_CARD_REMOVE); + sdhci_writel(host, intmask & SDHCI_INT_CARD_REMOVE, + SDHCI_INT_STATUS); tasklet_schedule(&host->card_tasklet); }