Commit 6379b237 authored by Alexander Stein's avatar Alexander Stein Committed by Chris Ball

mmc: sdhci: check interrupt flags in ISR again

When using MSI it is possible that a new MSI is sent while an earlier
MSI is currently handled. In this case SDHCI_INT_STATUS only contains
SDHCI_INT_RESPONSE and the ISR would not be called again. But at the end
of the ISR SDHCI_INT_DATA_END is now also pending which would be ignored.

Fix this by rereading the interrupt flags in the ISR until no interrupt
we care is pending.
Signed-off-by: default avatarAlexander Stein <alexander.stein@systec-electronic.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent e6039832
...@@ -2267,8 +2267,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -2267,8 +2267,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
{ {
irqreturn_t result; irqreturn_t result;
struct sdhci_host *host = dev_id; struct sdhci_host *host = dev_id;
u32 intmask; u32 intmask, unexpected = 0;
int cardint = 0; int cardint = 0, max_loops = 16;
spin_lock(&host->lock); spin_lock(&host->lock);
...@@ -2286,6 +2286,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -2286,6 +2286,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
goto out; goto out;
} }
again:
DBG("*** %s got interrupt: 0x%08x\n", DBG("*** %s got interrupt: 0x%08x\n",
mmc_hostname(host->mmc), intmask); mmc_hostname(host->mmc), intmask);
...@@ -2344,19 +2345,23 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -2344,19 +2345,23 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
intmask &= ~SDHCI_INT_CARD_INT; intmask &= ~SDHCI_INT_CARD_INT;
if (intmask) { if (intmask) {
pr_err("%s: Unexpected interrupt 0x%08x.\n", unexpected |= intmask;
mmc_hostname(host->mmc), intmask);
sdhci_dumpregs(host);
sdhci_writel(host, intmask, SDHCI_INT_STATUS); sdhci_writel(host, intmask, SDHCI_INT_STATUS);
} }
result = IRQ_HANDLED; result = IRQ_HANDLED;
mmiowb(); intmask = sdhci_readl(host, SDHCI_INT_STATUS);
if (intmask && --max_loops)
goto again;
out: out:
spin_unlock(&host->lock); spin_unlock(&host->lock);
if (unexpected) {
pr_err("%s: Unexpected interrupt 0x%08x.\n",
mmc_hostname(host->mmc), unexpected);
sdhci_dumpregs(host);
}
/* /*
* We have to delay this as it calls back into the driver. * We have to delay this as it calls back into the driver.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment