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; }