This patch adds SDHCI_QUIRK_BROKEN_CARD_DETECTION quirk. When specified, sdhci driver will set MMC_CAP_NEEDS_POLL MMC host capability, and won't enable card insert/remove interrupts.
This is needed for hosts with unreliable card detection, such as FSL eSDHC. The original eSDHC driver was tring to "debounce" card-detection IRQs by reading present state and disabling particular interrupts. But with this debouncing scheme I noticed that sometimes we miss card insertion/removal events. Signed-off-by: Anton Vorontsov <avoront...@ru.mvista.com> --- drivers/mmc/host/sdhci.c | 17 ++++++++++++++--- drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2728e90..782fb58 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -167,6 +167,9 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) { u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT; + if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) + return; + if (enable) sdhci_unmask_irqs(host, irqs); else @@ -1110,13 +1113,18 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) host->mrq = mrq; + if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) + goto send; + if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) || (host->flags & SDHCI_DEVICE_DEAD)) { host->mrq->cmd->error = -ENOMEDIUM; tasklet_schedule(&host->finish_tasklet); - } else - sdhci_send_command(host, mrq->cmd); - + goto out; + } +send: + sdhci_send_command(host, mrq->cmd); +out: mmiowb(); spin_unlock_irqrestore(&host->lock, flags); } @@ -1742,6 +1750,9 @@ int sdhci_add_host(struct sdhci_host *host) mmc->f_max = host->max_clk; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; + if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) + mmc->caps |= MMC_CAP_NEEDS_POLL; + if ((caps & SDHCI_CAN_DO_HISPD) || (host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED)) mmc->caps |= MMC_CAP_SD_HIGHSPEED; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 45c8309..b10920d 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -217,6 +217,8 @@ struct sdhci_host { #define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) /* Controller does not provide transfer-complete interrupt when not busy */ #define SDHCI_QUIRK_NO_BUSY_IRQ (1<<15) +/* Controller has unreliable card detection */ +#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<16) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ -- 1.5.6.5 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev