diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9b2284483cdd045acb1450e448d2a16da3928191..2b349d48fb9a8a8bcbdb1f552c3b7bf04cf07a37 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -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 diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 6e1acb628edc9412fd7e68500ab623cb97824c0e..6b789a739d4dfeb598a1fced82130ee05f1e4dc6 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -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);