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.
(cherry picked from commit a3f8f793b21782c79a9fcc5f7aa1cc27fcbf246e)
CRs-Fixed: 396706
Signed-off-by: Pratibhasagar V <pratibha@codeaurora.org>

Change-Id: Idfae18895abf47769328b0a768f83eba2ef573f7
Signed-off-by: Neha Pandey <nehap@codeaurora.org>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 353b439..386fa8e 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1761,6 +1761,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;
@@ -1802,6 +1803,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);
@@ -1830,6 +1837,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);
@@ -2807,6 +2820,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 */