aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-04-20 12:27:13 -0400
committerChris Ball <cjb@laptop.org>2012-07-21 00:02:15 -0400
commit7d17baa05da6a2e64ee15011cdf4319bd3e0ff61 (patch)
tree9fe6a2658adf59ce0d0564e9e5579329de6c82a8
parente2ee996eaad64c149cb7cfd344789c7e0c1577dc (diff)
mmc: sh_mmcif: add regulator support
Add regulator support to the sh_mmcif driver, but also preserve the current power-callback. Also note, that the card power is not switched off during clock gating periods, hence there's no need to power it on every time the card is re-activated. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Reviewed-by: Simon Horman <horms@verge.net.au> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/sh_mmcif.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 468027665ede..204bcedc2164 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -923,10 +923,22 @@ static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
923 return ret; 923 return ret;
924} 924}
925 925
926static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
927{
928 struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
929 struct mmc_host *mmc = host->mmc;
930
931 if (pd->set_pwr)
932 pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
933 if (!IS_ERR(mmc->supply.vmmc))
934 /* Errors ignored... */
935 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
936 ios->power_mode ? ios->vdd : 0);
937}
938
926static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 939static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
927{ 940{
928 struct sh_mmcif_host *host = mmc_priv(mmc); 941 struct sh_mmcif_host *host = mmc_priv(mmc);
929 struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
930 unsigned long flags; 942 unsigned long flags;
931 943
932 spin_lock_irqsave(&host->lock, flags); 944 spin_lock_irqsave(&host->lock, flags);
@@ -944,6 +956,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
944 sh_mmcif_request_dma(host, host->pd->dev.platform_data); 956 sh_mmcif_request_dma(host, host->pd->dev.platform_data);
945 host->card_present = true; 957 host->card_present = true;
946 } 958 }
959 sh_mmcif_set_power(host, ios);
947 } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { 960 } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
948 /* clock stop */ 961 /* clock stop */
949 sh_mmcif_clock_control(host, 0); 962 sh_mmcif_clock_control(host, 0);
@@ -957,8 +970,8 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
957 pm_runtime_put(&host->pd->dev); 970 pm_runtime_put(&host->pd->dev);
958 clk_disable(host->hclk); 971 clk_disable(host->hclk);
959 host->power = false; 972 host->power = false;
960 if (p->set_pwr && ios->power_mode == MMC_POWER_OFF) 973 if (ios->power_mode == MMC_POWER_OFF)
961 p->set_pwr(host->pd, 0); 974 sh_mmcif_set_power(host, ios);
962 } 975 }
963 host->state = STATE_IDLE; 976 host->state = STATE_IDLE;
964 return; 977 return;
@@ -966,8 +979,6 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
966 979
967 if (ios->clock) { 980 if (ios->clock) {
968 if (!host->power) { 981 if (!host->power) {
969 if (p->set_pwr)
970 p->set_pwr(host->pd, ios->power_mode);
971 sh_mmcif_clk_update(host); 982 sh_mmcif_clk_update(host);
972 pm_runtime_get_sync(&host->pd->dev); 983 pm_runtime_get_sync(&host->pd->dev);
973 host->power = true; 984 host->power = true;
@@ -1251,6 +1262,19 @@ static void mmcif_timeout_work(struct work_struct *work)
1251 mmc_request_done(host->mmc, mrq); 1262 mmc_request_done(host->mmc, mrq);
1252} 1263}
1253 1264
1265static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
1266{
1267 struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
1268 struct mmc_host *mmc = host->mmc;
1269
1270 mmc_regulator_get_supply(mmc);
1271
1272 if (!mmc->ocr_avail)
1273 mmc->ocr_avail = pd->ocr;
1274 else if (pd->ocr)
1275 dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
1276}
1277
1254static int __devinit sh_mmcif_probe(struct platform_device *pdev) 1278static int __devinit sh_mmcif_probe(struct platform_device *pdev)
1255{ 1279{
1256 int ret = 0, irq[2]; 1280 int ret = 0, irq[2];
@@ -1298,8 +1322,8 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
1298 spin_lock_init(&host->lock); 1322 spin_lock_init(&host->lock);
1299 1323
1300 mmc->ops = &sh_mmcif_ops; 1324 mmc->ops = &sh_mmcif_ops;
1301 if (pd->ocr) 1325 sh_mmcif_init_ocr(host);
1302 mmc->ocr_avail = pd->ocr; 1326
1303 mmc->caps = MMC_CAP_MMC_HIGHSPEED; 1327 mmc->caps = MMC_CAP_MMC_HIGHSPEED;
1304 if (pd->caps) 1328 if (pd->caps)
1305 mmc->caps |= pd->caps; 1329 mmc->caps |= pd->caps;