From 2858ae8aceb39b24d51eec05975d93b73ca271d2 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Tue, 6 Aug 2013 15:22:28 +0530 Subject: [PATCH] mmc: sdhci-msm: Fix power IRQ issue uncovered in 3.10 kernel The request to change the VDD I/O voltage level to high/low will trigger an IRQ only when - 1. SWITCHABLE_SIGNALING_VOLTAGE bit 29 of SDCC_MCI_GENERICS register is set. 2. Above condition is true and when there is a state change in VDD bit 3 of SDHCi Host Control 2 register. Until now, the MMC core layer issues I/O high request only after the controller is powered up. The I/O high request is same as the reset state of host control2 register which will never trigger an IRQ. The driver already handles this case by ensuring that I/O voltage is set to high as part of power up itself and thus returns immediately when I/O high request is issued later. But in 3.10 kernel, this request is issued even before the controller is powered up. Hence, check for host->pwr state to avoid waiting for an IRQ that never comes. Change-Id: I31b6723f53397be1ba151305ead89e739560eb20 Signed-off-by: Sahitya Tummala --- drivers/mmc/host/sdhci-msm.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index f2fb9f56564a..9ec0ec0baf84 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -43,6 +43,9 @@ #define CORE_HC_MODE 0x78 #define HC_MODE_EN 0x1 +#define CORE_GENERICS 0x70 +#define SWITCHABLE_SIGNALLING_VOL (1 << 29) + #define CORE_POWER 0x0 #define CORE_SW_RST (1 << 7) @@ -1891,11 +1894,36 @@ static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type) struct sdhci_msm_host *msm_host = pltfm_host->priv; unsigned long flags; bool done = false; + u32 io_sig_sts; spin_lock_irqsave(&host->lock, flags); pr_debug("%s: %s: request %d curr_pwr_state %x curr_io_level %x\n", mmc_hostname(host->mmc), __func__, req_type, msm_host->curr_pwr_state, msm_host->curr_io_level); + io_sig_sts = readl_relaxed(msm_host->core_mem + CORE_GENERICS); + /* + * The IRQ for request type IO High/Low will be generated when - + * 1. SWITCHABLE_SIGNALLING_VOL is enabled in HW. + * 2. If 1 is true and when there is a state change in 1.8V enable + * bit (bit 3) of SDHCI_HOST_CONTROL2 register. The reset state of + * that bit is 0 which indicates 3.3V IO voltage. So, when MMC core + * layer tries to set it to 3.3V before card detection happens, the + * IRQ doesn't get triggered as there is no state change in this bit. + * The driver already handles this case by changing the IO voltage + * level to high as part of controller power up sequence. Hence, check + * for host->pwr to handle a case where IO voltage high request is + * issued even before controller power up. + */ + if (req_type & (REQ_IO_HIGH | REQ_IO_LOW)) { + if (!(io_sig_sts & SWITCHABLE_SIGNALLING_VOL) || + ((req_type & REQ_IO_HIGH) && !host->pwr)) { + pr_debug("%s: do not wait for power IRQ that never comes\n", + mmc_hostname(host->mmc)); + spin_unlock_irqrestore(&host->lock, flags); + return; + } + } + if ((req_type & msm_host->curr_pwr_state) || (req_type & msm_host->curr_io_level)) done = true;