aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sh_mmcif.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-04-19 18:02:50 +0200
committerChris Ball <cjb@laptop.org>2012-07-21 00:02:14 -0400
commita6609267107ecc5598b79aa353036c1f57e7257e (patch)
tree15b29b3bde658c73f0a1c3d1fab944042ad83a38 /drivers/mmc/host/sh_mmcif.c
parentmmc: sh_mmcif: fix clock management (diff)
downloadlinux-dev-a6609267107ecc5598b79aa353036c1f57e7257e.tar.xz
linux-dev-a6609267107ecc5598b79aa353036c1f57e7257e.zip
mmc: sh_mmcif: re-read the clock frequency every time it is turned on
With aggressive clock gating the clock can be disabled during interface inactivity. During this time its frequency can be changed by another its user. Therefore when the interface is activated again and the clock is re-enabled, its frequency has to be re-read. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Reviewed-by: Simon Horman <horms@verge.net.au> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/sh_mmcif.c')
-rw-r--r--drivers/mmc/host/sh_mmcif.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 6a93b0466854..3ffb92fc084e 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -910,6 +910,19 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
sh_mmcif_start_cmd(host, mrq);
}
+static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
+{
+ int ret = clk_enable(host->hclk);
+
+ if (!ret) {
+ host->clk = clk_get_rate(host->hclk);
+ host->mmc->f_max = host->clk / 2;
+ host->mmc->f_min = host->clk / 512;
+ }
+
+ return ret;
+}
+
static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sh_mmcif_host *host = mmc_priv(mmc);
@@ -955,7 +968,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (!host->power) {
if (p->set_pwr)
p->set_pwr(host->pd, ios->power_mode);
- clk_enable(host->hclk);
+ sh_mmcif_clk_update(host);
pm_runtime_get_sync(&host->pd->dev);
host->power = true;
sh_mmcif_sync_reset(host);
@@ -1308,10 +1321,9 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
goto eclkget;
}
- clk_enable(host->hclk);
- host->clk = clk_get_rate(host->hclk);
- mmc->f_max = host->clk / 2;
- mmc->f_min = host->clk / 512;
+ ret = sh_mmcif_clk_update(host);
+ if (ret < 0)
+ goto eclkupdate;
ret = pm_runtime_resume(&pdev->dev);
if (ret < 0)
@@ -1353,6 +1365,7 @@ ereqirq0:
pm_runtime_suspend(&pdev->dev);
eresume:
clk_disable(host->hclk);
+eclkupdate:
clk_put(host->hclk);
eclkget:
pm_runtime_disable(&pdev->dev);