diff options
author | Jisheng Zhang <jszhang@marvell.com> | 2015-01-04 10:15:47 -0500 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2015-01-19 03:56:31 -0500 |
commit | 62cf983ad84275f8580c807e5e596216c46773cf (patch) | |
tree | 574a4849322e2d746f7057e4eddb54c5e2270a30 | |
parent | 250fb7b45031fd56f5f54da27ffc6fe05abea98e (diff) |
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>
-rw-r--r-- | drivers/mmc/host/sdhci-pxav3.c | 7 |
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) | |||
365 | } | 365 | } |
366 | } | 366 | } |
367 | 367 | ||
368 | pm_runtime_enable(&pdev->dev); | 368 | pm_runtime_get_noresume(&pdev->dev); |
369 | pm_runtime_get_sync(&pdev->dev); | 369 | pm_runtime_set_active(&pdev->dev); |
370 | pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); | 370 | pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); |
371 | pm_runtime_use_autosuspend(&pdev->dev); | 371 | pm_runtime_use_autosuspend(&pdev->dev); |
372 | pm_runtime_enable(&pdev->dev); | ||
372 | pm_suspend_ignore_children(&pdev->dev, 1); | 373 | pm_suspend_ignore_children(&pdev->dev, 1); |
373 | 374 | ||
374 | ret = sdhci_add_host(host); | 375 | ret = sdhci_add_host(host); |
@@ -391,8 +392,8 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
391 | return 0; | 392 | return 0; |
392 | 393 | ||
393 | err_add_host: | 394 | err_add_host: |
394 | pm_runtime_put_sync(&pdev->dev); | ||
395 | pm_runtime_disable(&pdev->dev); | 395 | pm_runtime_disable(&pdev->dev); |
396 | pm_runtime_put_noidle(&pdev->dev); | ||
396 | err_of_parse: | 397 | err_of_parse: |
397 | err_cd_req: | 398 | err_cd_req: |
398 | err_mbus_win: | 399 | err_mbus_win: |