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 <stummala@codeaurora.org>
This commit is contained in:
parent
0c6d03791c
commit
2858ae8ace
1 changed files with 28 additions and 0 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue