summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-pxav3.c
diff options
context:
space:
mode:
authorJisheng Zhang2015-01-04 16:15:47 +0100
committerUlf Hansson2015-01-19 09:56:31 +0100
commit62cf983ad84275f8580c807e5e596216c46773cf (patch)
tree574a4849322e2d746f7057e4eddb54c5e2270a30 /drivers/mmc/host/sdhci-pxav3.c
parentmmc: sdhci: Always init buf_ready_int (diff)
downloadkernel-qcow2-linux-62cf983ad84275f8580c807e5e596216c46773cf.tar.gz
kernel-qcow2-linux-62cf983ad84275f8580c807e5e596216c46773cf.tar.xz
kernel-qcow2-linux-62cf983ad84275f8580c807e5e596216c46773cf.zip
mmc: sdhci-pxav3: fix unbalanced clock issues during probe
Commit 0dcaa2499b7d ("sdhci-pxav3: Fix runtime PM initialization") tries to fix one hang issue caused by calling sdhci_add_host() on a suspended device. The fix enables the clock twice, once by clk_prepare_enable() and another by pm_runtime_get_sync(), meaning that the clock will never be gated at runtime PM suspend. I observed the power consumption regression on Marvell BG2Q SoCs. In fact, the fix is not correct. There still be a very small window during which a runtime suspend might somehow occur after pm_runtime_enable() but before pm_runtime_get_sync(). This patch fixes all of the two problems by just incrementing the usage counter before pm_runtime_enable(). It also adjust the order of disabling runtime pm and storing the usage count in the error path to handle clock gating properly. Signed-off-by: Jisheng Zhang <jszhang@marvell.com> Cc: <stable@vger.kernel.org> # v3.11+ Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sdhci-pxav3.c')
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index ca3424e7ef71..1255dd2b91c1 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -365,10 +365,11 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
}
}
- pm_runtime_enable(&pdev->dev);
- pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_get_noresume(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS);
pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
pm_suspend_ignore_children(&pdev->dev, 1);
ret = sdhci_add_host(host);
@@ -391,8 +392,8 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
return 0;
err_add_host:
- pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
err_of_parse:
err_cd_req:
err_mbus_win: