mmc: msm_sdcc: Reset interrupt MASK register (MCI_MASK0) on powering off

In one corner case, the SD card is stuck in a bad state with its DAT0
line pulled low, and SDCC is waiting on the interrupt when the line
goes back high. But due its bad state eventually the SD card is removed
from the system.

Later during re-scanning of the devices, the SD card is power-cycled and
added to the system. But now the pending interrupts for SD card is
received as the interrupt MASK register (MCI_MASK0) was not cleared.

To prevent such cases reset the interrupt MASK register (MCI_MASK0) while
powering off to prevent any pending interrupts after power-cycle.

CRs-Fixed: 396706
Change-Id: I83c087a76cd92f20c5990a787296e093a13478ad
Signed-off-by: Pratibhasagar V <pratibha@codeaurora.org>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 2c98816..ed84f4a 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1779,6 +1779,7 @@
 msmsdcc_irq(int irq, void *dev_id)
 {
 	struct msmsdcc_host	*host = dev_id;
+	struct mmc_host		*mmc = host->mmc;
 	u32			status;
 	int			ret = 0;
 	int			timer = 0;
@@ -1820,6 +1821,12 @@
 				 */
 				wake_lock(&host->sdio_wlock);
 			} else {
+				if (!mmc->card || !mmc_card_sdio(mmc->card)) {
+					WARN(1, "%s: SDCC core interrupt received for non-SDIO cards when SDCC clocks are off\n",
+					     mmc_hostname(mmc));
+					ret = 1;
+					break;
+				}
 				spin_unlock(&host->lock);
 				mmc_signal_sdio_irq(host->mmc);
 				spin_lock(&host->lock);
@@ -1848,6 +1855,12 @@
 #endif
 
 		if (status & MCI_SDIOINTROPE) {
+			if (!mmc->card || mmc_card_sdio(mmc->card)) {
+				WARN(1, "%s: SDIO interrupt received for non-SDIO card\n",
+					mmc_hostname(mmc));
+				ret = 1;
+				break;
+			}
 			if (host->sdcc_suspending)
 				wake_lock(&host->sdio_suspend_wlock);
 			spin_unlock(&host->lock);
@@ -2825,6 +2838,14 @@
 		msmsdcc_set_vdd_io_vol(host, VDD_IO_LOW, 0);
 		msmsdcc_update_io_pad_pwr_switch(host);
 		msmsdcc_setup_pins(host, false);
+		/*
+		 * Reset the mask to prevent hitting any pending interrupts
+		 * after powering up the card again.
+		 */
+		if (atomic_read(&host->clks_on)) {
+			writel_relaxed(0, host->base + MMCIMASK0);
+			mb();
+		}
 		break;
 	case MMC_POWER_UP:
 		/* writing PWR_UP bit is redundant */