aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorLudovic Barre <ludovic.barre@stericsson.com>2011-02-25 11:08:52 +0100
committerSebastian RASMUSSEN <sebastian.rasmussen@stericsson.com>2011-04-07 16:05:41 +0200
commit7458d6ff60e055956e221d3e5775903c7b030a59 (patch)
treefb2b35d933d5639519c7e667edd7bfd91f535207 /drivers/mmc
parent104f06d9e3b4f6ad7ec55d5ee13c88a5299d5c2e (diff)
mmci: centralizes imasks managment
ST-Ericsson Linux next: N/A ST-Ericsson ID: - ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I8a88e2b4ea2357e5f237ca23e2cec2701e68145a Signed-off-by: Ludovic Barre <ludovic.barre@stericsson.com> Conflicts: drivers/mmc/host/mmci.c Change-Id: I8a88e2b4ea2357e5f237ca23e2cec2701e68145a Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/17177 Reviewed-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com> Tested-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmci.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 4114c17c25b..427318fde3b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -289,20 +289,35 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
spin_lock(&host->lock);
}
-static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
-{
- void __iomem *base = host->base;
+static void mmci_set_mask1(struct mmci_host *host, u32 mask)
+{
if (host->singleirq) {
- unsigned int mask0 = readl(base + MMCIMASK0);
+ host->mmci_mask0 &= ~MCI_IRQ1MASK;
+ host->mmci_mask0 |= (mask & MCI_IRQ1MASK);
+ }
+ host->mmci_mask1 = mask;
+}
- mask0 &= ~MCI_IRQ1MASK;
- mask0 |= mask;
+static inline void enable_imasks(struct mmci_host *host)
+{
+ writel(host->mmci_mask0, host->base + MMCIMASK0);
+ writel(host->mmci_mask1, host->base + MMCIMASK1);
+}
- writel(mask0, base + MMCIMASK0);
- }
+static inline void disable_imasks(struct mmci_host *host)
+{
+ writel(0, host->base + MMCIMASK0);
+ writel(0, host->base + MMCIMASK1);
+}
- writel(mask, base + MMCIMASK1);
+static inline void clear_imasks(struct mmci_host *host)
+{
+ /* preserve the SDIO IRQ mask state */
+ host->mmci_mask0 &= MCI_SDIOITMASK;
+ host->mmci_mask1 = 0;
+ writel(host->mmci_mask0, host->base + MMCIMASK0);
+ writel(host->mmci_mask1, host->base + MMCIMASK1);
}
static void mmci_stop_data(struct mmci_host *host)
@@ -1417,6 +1432,9 @@ static int mmci_enable(struct mmc_host *mmc)
writel(host->mmci_power, host->base + MMCIPOWER);
writel(host->mmci_clockctrl, host->base + MMCICLOCK);
+ /* SDIO IT is re-enabled, if there are any subcribers */
+ enable_imasks(host);
+
spin_unlock_irqrestore(&host->lock, flags);
return ret;
@@ -1428,6 +1446,14 @@ static int mmci_disable(struct mmc_host *mmc, int lazy)
struct mmci_host *host = mmc_priv(mmc);
/*
+ * Make sure we do not get any interrupts when disable is done
+ * of the clock and the regulator. Especially important for SDIO
+ * interrupts, since they may occur even without any active
+ * request handling ongoing.
+ */
+ disable_imasks(host);
+
+ /*
* To be able to handle specific shutdown scenarios for each host,
* the following function shall be implemented.
*/