From 1f59df2378b698b203038a2e58ff6ebc3e6ec447 Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Wed, 12 Jan 2022 09:50:15 +0530 Subject: [PATCH] mmc: sdhci-msm: Send a disable vote to make RMP driver consistent Removing SD card at UEFI/XBL stage can lead to regulator getting turned off due to MGPI but RPM isn't aware of that. Kernel comes up with vote_count = 0 and we call enable API but RPM ignores this thinking that it is already turned on leading the vdd regulator in OFF state despite our vote. CMD timeouts are seen in our sd_init path due to this and card detection fails. After the first enable vote, send a disable vote followed by re-enable vote to make the RPM driver consistent with the regulator state. Change-Id: Ifb761d07f13daa271c10c5454195f9e55ef17833 Signed-off-by: Sarthak Garg Reviewed-on: https://gerrit.mot.com/2193867 Reviewed-by: Chuanchun Zhu SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- drivers/mmc/host/sdhci-msm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 6a88499d1c90..c3109e864e6c 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -474,6 +474,7 @@ struct sdhci_msm_host { int sdiowakeup_irq; bool is_sdiowakeup_enabled; bool sdio_pending_processing; + bool first_power_on; }; static struct sdhci_msm_host *sdhci_slot[2]; @@ -2264,8 +2265,14 @@ static int sdhci_msm_setup_vreg(struct sdhci_msm_host *msm_host, for (i = 0; i < ARRAY_SIZE(vreg_table); i++) { if (vreg_table[i]) { - if (enable) + if (enable) { ret = sdhci_msm_vreg_enable(vreg_table[i]); + if (msm_host->first_power_on && !(mmc->caps & MMC_CAP_NONREMOVABLE)) { + ret = sdhci_msm_vreg_disable(vreg_table[i]); + msleep(1); + ret = sdhci_msm_vreg_enable(vreg_table[i]); + } + } else ret = sdhci_msm_vreg_disable(vreg_table[i]); if (ret) @@ -2273,6 +2280,9 @@ static int sdhci_msm_setup_vreg(struct sdhci_msm_host *msm_host, } } + if (enable && !(mmc->caps & MMC_CAP_NONREMOVABLE)) + msm_host->first_power_on = false; + if (enable && !(mmc->caps & MMC_CAP_NONREMOVABLE)) { /* @@ -4297,6 +4307,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) msm_host = sdhci_pltfm_priv(pltfm_host); msm_host->mmc = host->mmc; msm_host->pdev = pdev; + msm_host->first_power_on = true; ret = mmc_of_parse(host->mmc); if (ret)