aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sh_mmcif.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-04-19 12:02:50 -0400
committerChris Ball <cjb@laptop.org>2012-07-21 00:02:14 -0400
commita6609267107ecc5598b79aa353036c1f57e7257e (patch)
tree15b29b3bde658c73f0a1c3d1fab944042ad83a38 /drivers/mmc/host/sh_mmcif.c
parentb289174ff70a591545a054d52ae081a75a73f085 (diff)
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)
910 sh_mmcif_start_cmd(host, mrq); 910 sh_mmcif_start_cmd(host, mrq);
911} 911}
912 912
913static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
914{
915 int ret = clk_enable(host->hclk);
916
917 if (!ret) {
918 host->clk = clk_get_rate(host->hclk);
919 host->mmc->f_max = host->clk / 2;
920 host->mmc->f_min = host->clk / 512;
921 }
922
923 return ret;
924}
925
913static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 926static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
914{ 927{
915 struct sh_mmcif_host *host = mmc_priv(mmc); 928 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)
955 if (!host->power) { 968 if (!host->power) {
956 if (p->set_pwr) 969 if (p->set_pwr)
957 p->set_pwr(host->pd, ios->power_mode); 970 p->set_pwr(host->pd, ios->power_mode);
958 clk_enable(host->hclk); 971 sh_mmcif_clk_update(host);
959 pm_runtime_get_sync(&host->pd->dev); 972 pm_runtime_get_sync(&host->pd->dev);
960 host->power = true; 973 host->power = true;
961 sh_mmcif_sync_reset(host); 974 sh_mmcif_sync_reset(host);
@@ -1308,10 +1321,9 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
1308 dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret); 1321 dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
1309 goto eclkget; 1322 goto eclkget;
1310 } 1323 }
1311 clk_enable(host->hclk); 1324 ret = sh_mmcif_clk_update(host);
1312 host->clk = clk_get_rate(host->hclk); 1325 if (ret < 0)
1313 mmc->f_max = host->clk / 2; 1326 goto eclkupdate;
1314 mmc->f_min = host->clk / 512;
1315 1327
1316 ret = pm_runtime_resume(&pdev->dev); 1328 ret = pm_runtime_resume(&pdev->dev);
1317 if (ret < 0) 1329 if (ret < 0)
@@ -1353,6 +1365,7 @@ ereqirq0:
1353 pm_runtime_suspend(&pdev->dev); 1365 pm_runtime_suspend(&pdev->dev);
1354eresume: 1366eresume:
1355 clk_disable(host->hclk); 1367 clk_disable(host->hclk);
1368eclkupdate:
1356 clk_put(host->hclk); 1369 clk_put(host->hclk);
1357eclkget: 1370eclkget:
1358 pm_runtime_disable(&pdev->dev); 1371 pm_runtime_disable(&pdev->dev);