From 283e8d1b9311c0939f6eab8355a01b2843865162 Mon Sep 17 00:00:00 2001 From: Sayali Lokhande Date: Fri, 18 Nov 2016 16:05:50 +0530 Subject: [PATCH] mmc: sdhci-msm: Disable controller clocks in suspend Generally, during card suspend we call mmc_power_off and disable controller clocks. Now consider below sequence of events : suspend -> resume -> suspend. 1) During first platform suspend, mmc_power_off will be called and clocks would be disabled. 2) As a part of platform resume, we enable controller clocks and defer card resume when MMC_BUSRESUME_NEEDS_RESUME flag is set. 3) During next suspend we check if card is already suspended (i.e MMC_BUSRESUME_NEEDS_RESUME is set) and return without doing actual suspend (where we call mmc_power_off and disable controller clocks). So in this scenario, controller clocks will remain ON even though card state is SUSPENDED. Fix this by disabling controller clocks during suspend if controller clock was ON. CRs-Fixed: 1088893 Change-Id: Id54a15d7f6a7131dab609eec1db158c64ada83ce Signed-off-by: Sayali Lokhande --- drivers/mmc/host/sdhci-msm.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 466e0a2c8483..6822080dc2bb 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2906,7 +2906,24 @@ out: return rc; } +static void sdhci_msm_disable_controller_clock(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_msm_host *msm_host = pltfm_host->priv; + if (atomic_read(&msm_host->controller_clock)) { + if (!IS_ERR(msm_host->clk)) + clk_disable_unprepare(msm_host->clk); + if (!IS_ERR(msm_host->pclk)) + clk_disable_unprepare(msm_host->pclk); + if (!IS_ERR(msm_host->ice_clk)) + clk_disable_unprepare(msm_host->ice_clk); + sdhci_msm_bus_voting(host, 0); + atomic_set(&msm_host->controller_clock, 0); + pr_debug("%s: %s: disabled controller clock\n", + mmc_hostname(host->mmc), __func__); + } +} static int sdhci_msm_prepare_clocks(struct sdhci_host *host, bool enable) { @@ -4848,7 +4865,7 @@ static int sdhci_msm_suspend(struct device *dev) } ret = sdhci_msm_runtime_suspend(dev); out: - + sdhci_msm_disable_controller_clock(host); if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { sdio_cfg = sdhci_msm_cfg_sdio_wakeup(host, true); if (sdio_cfg)