aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@linaro.org>2011-05-05 14:33:40 +0200
committerHenrik Aberg <henrik.aberg@stericsson.com>2011-05-18 09:39:49 +0200
commit5046283c72a700f938b378a90632627371ee0e82 (patch)
tree502936687a4c623a760bb15e3dec2db3752ac71e /drivers/mmc
parent1a306c067df48dd91ad8f5889f656f68f7d96a20 (diff)
MMCI: Fixup handling of MCI_SDIOIT irq mask
Make sure the MCI_SDIOIT irq mask is never accessed and modified without holding the host spinlock. As well re-order some actions in the enable and disable functions to handle SDIO irq wakeups event sequence correctly. Change-Id: Ia24fa162ee13ac767828bcca19c1ccd31cc7f695 Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/16948 Reviewed-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com> Conflicts: drivers/mmc/host/mmci.c
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmci.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 389f5e3194c..f85927eaa0c 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -934,6 +934,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
{
struct mmci_host *host = dev_id;
u32 status;
+ int sdio_irq = 0;
int ret = 0;
spin_lock(&host->lock);
@@ -957,7 +958,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
if (status & MCI_ST_SDIOIT)
- mmc_signal_sdio_irq(host->mmc);
+ sdio_irq = 1;
data = host->data;
if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|
@@ -973,6 +974,9 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
spin_unlock(&host->lock);
+ if (sdio_irq)
+ mmc_signal_sdio_irq(host->mmc);
+
return IRQ_RETVAL(ret);
}
@@ -1122,24 +1126,19 @@ static irqreturn_t mmci_cd_irq(int irq, void *dev_id)
static void mmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
unsigned long flags;
+ unsigned int mask0;
struct mmci_host *host = mmc_priv(mmc);
- if (enable) {
- /*
- * Since the host is not claimed when doing enable
- * we must handle it here.
- */
- spin_lock_irqsave(&host->lock, flags);
+ spin_lock_irqsave(&host->lock, flags);
- writel((readl(host->base + MMCIMASK0) | MCI_ST_SDIOIT),
- (host->base + MMCIMASK0));
+ mask0 = readl(host->base + MMCIMASK0);
+ if (enable)
+ mask0 |= MCI_ST_SDIOIT;
+ else
+ mask0 &= ~MCI_ST_SDIOIT;
+ writel(mask0, host->base + MMCIMASK0);
- spin_unlock_irqrestore(&host->lock, flags);
- } else {
- /* We assumes the host is claimed when doing disable. */
- writel((readl(host->base + MMCIMASK0) & ~MCI_ST_SDIOIT),
- (host->base + MMCIMASK0));
- }
+ spin_unlock_irqrestore(&host->lock, flags);
}
static const struct mmc_host_ops mmci_ops = {