From accb1dbb52f10397ae849e7a9161647f0e4aa006 Mon Sep 17 00:00:00 2001 From: "Bao D. Nguyen" Date: Thu, 9 Apr 2020 15:57:49 -0700 Subject: [PATCH] mmc: sdhci-msm: Avoid enable SD power if card is not present Properly avoid turn on the SD card power when SD card is removed. In some multi card tray designs, removing the SD card may cause the SD card power supply pin to come in contact with the SIM card. This change is to ensure the SD card power is not active when the SD card is removed. As a result, avoid possible damage to the SIM card in case the SD card power makes contact with the SIM card. Change-Id: I45a2bb434bd2bc76957ae382eecd5cce9e743918 Signed-off-by: Bao D. Nguyen --- drivers/mmc/host/sdhci-msm.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 9d86fe96d303..2e6185817af0 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1693,6 +1693,7 @@ static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type) u32 val = SWITCHABLE_SIGNALING_VOLTAGE; const struct sdhci_msm_offset *msm_offset = msm_host->offset; + struct mmc_host *mmc = host->mmc; pr_debug("%s: %s: request %d curr_pwr_state %x curr_io_level %x\n", mmc_hostname(host->mmc), __func__, req_type, @@ -1729,6 +1730,13 @@ static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type) mmc_hostname(host->mmc), req_type); return; } + + if (mmc->ops->get_cd && !mmc->ops->get_cd(mmc)) { + pr_debug("%s: card is not present. Do not wait for pwr irq\n", + mmc_hostname(host->mmc)); + return; + } + if ((req_type & msm_host->curr_pwr_state) || (req_type & msm_host->curr_io_level)) done = true; @@ -2058,6 +2066,7 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) u32 config; const struct sdhci_msm_offset *msm_offset = msm_host->offset; int ret = 0; + struct mmc_host *mmc = host->mmc; irq_status = msm_host_readl(msm_host, host, msm_offset->core_pwrctl_status); @@ -2088,6 +2097,13 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) udelay(10); } + if (mmc->ops->get_cd && !mmc->ops->get_cd(mmc) && + irq_status & CORE_PWRCTL_BUS_ON) { + irq_ack = CORE_PWRCTL_BUS_FAIL; + msm_host_writel(msm_host, irq_ack, host, + msm_offset->core_pwrctl_ctl); + return; + } /* Handle BUS ON/OFF*/ if (irq_status & CORE_PWRCTL_BUS_ON) { ret = sdhci_msm_setup_vreg(msm_host->pdata, true, false); @@ -2200,7 +2216,6 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) msm_host->pwr_irq_flag = 1; sdhci_msm_complete_pwr_irq_wait(msm_host); - return IRQ_HANDLED; }