@@ -2460,12 +2460,18 @@ again:
if (intmask & SDHCI_INT_CMD_MASK) {
sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
SDHCI_INT_STATUS);
+ if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) &&
+ (host->clock <= 400000))
+ udelay(40);
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
}
if (intmask & SDHCI_INT_DATA_MASK) {
sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
SDHCI_INT_STATUS);
+ if ((host->quirks2 & SDHCI_QUIRK2_SLOW_INT_CLR) &&
+ (host->clock <= 400000))
+ udelay(40);
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
}
@@ -100,6 +100,8 @@ struct sdhci_host {
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
/* Controller cannot de-assert Read/Write Transfer Active after transaction */
#define SDHCI_QUIRK2_RDWR_TX_ACTIVE_EOT (1<<6)
+/* Controller clears interrupt slowly and IRQ handler may be called twice */
+#define SDHCI_QUIRK2_SLOW_INT_CLR (1<<7)
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
Initial version of Qualcomm SDHC has a hardware issue. This patch adds a quirk SDHCI_QUIRK2_SLOW_INT_CLR to enable a workaround. Hardware issue: Slow interrupt clearance at 400KHz may cause host driver interrupt handler to be called twice. Software workaround: Add 40us delay in interrupt handler when operating at initialization frequency(400KHz). CC: Venkat Gopalakrishnan <venkatg@codeaurora.org> CC: Asutosh Das <asutoshd@codeaurora.org> CC: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: Georgi Djakov <gdjakov@mm-sol.com> --- drivers/mmc/host/sdhci.c | 6 ++++++ include/linux/mmc/sdhci.h | 2 ++ 2 files changed, 8 insertions(+)