mmc: tmio: discard obsolete SDIO irqs before enabling irqs
authorWolfram Sang <wsa+renesas@sang-engineering.com>
Thu, 19 Jan 2017 20:07:18 +0000 (21:07 +0100)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 13 Feb 2017 12:20:35 +0000 (13:20 +0100)
Before enabling SDIO irqs, clear the status bit, so we discard old and
stale interrupts. Needed to get two wireless cards working. Use the
newly introduced macro in all places.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_pio.c

index 9b2284483cdd045acb1450e448d2a16da3928191..2b349d48fb9a8a8bcbdb1f552c3b7bf04cf07a37 100644 (file)
@@ -91,6 +91,8 @@
 #define TMIO_SDIO_STAT_EXWT    0x8000
 #define TMIO_SDIO_MASK_ALL     0xc007
 
+#define TMIO_SDIO_SETBITS_MASK 0x0006
+
 /* Define some IRQ masks */
 /* This is the mask used at reset by the chip */
 #define TMIO_MASK_ALL           0x837f031d
index 6e1acb628edc9412fd7e68500ab623cb97824c0e..6b789a739d4dfeb598a1fced82130ee05f1e4dc6 100644 (file)
@@ -134,12 +134,21 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
        struct tmio_mmc_host *host = mmc_priv(mmc);
 
        if (enable && !host->sdio_irq_enabled) {
+               u16 sdio_status;
+
                /* Keep device active while SDIO irq is enabled */
                pm_runtime_get_sync(mmc_dev(mmc));
-               host->sdio_irq_enabled = true;
 
+               host->sdio_irq_enabled = true;
                host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
                                        ~TMIO_SDIO_STAT_IOIRQ;
+
+               /* Clear obsolete interrupts before enabling */
+               sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS) & ~TMIO_SDIO_MASK_ALL;
+               if (host->pdata->flags & TMIO_MMC_SDIO_STATUS_SETBITS)
+                       sdio_status |= TMIO_SDIO_SETBITS_MASK;
+               sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status);
+
                sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
        } else if (!enable && host->sdio_irq_enabled) {
                host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
@@ -724,7 +733,7 @@ static void __tmio_mmc_sdio_irq(struct tmio_mmc_host *host)
 
        sdio_status = status & ~TMIO_SDIO_MASK_ALL;
        if (pdata->flags & TMIO_MMC_SDIO_STATUS_SETBITS)
-               sdio_status |= 6;
+               sdio_status |= TMIO_SDIO_SETBITS_MASK;
 
        sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status);