aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorJisheng Zhang <jszhang@marvell.com>2015-12-11 08:36:29 -0500
committerUlf Hansson <ulf.hansson@linaro.org>2015-12-28 06:51:39 -0500
commit918f4cbd4340ddd1eb389cd8efa3b07ac74ec4c0 (patch)
tree3f12f666e0b530fe26c646246cd52a99ec1f66f6 /drivers/mmc
parent520322d92eab66b6fee562557fdd201b01cd6240 (diff)
mmc: sdhci: restore behavior when setting VDD via external regulator
After commit 52221610dd84 ("mmc: sdhci: Improve external VDD regulator support"), for the VDD is supplied via external regulators, we ignore the code to convert a VDD voltage request into one of the standard SDHCI voltage levels, then program it in the SDHCI_POWER_CONTROL. This brings two issues: 1. SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON quirk isn't handled properly any more. 2. What's more, once SDHCI_POWER_ON bit is set, some controllers such as the sdhci-pxav3 used in marvell berlin SoCs require the voltage levels programming in the SDHCI_POWER_CONTROL register, even the VDD is supplied by external regulator. So the host in marvell berlin SoCs still works fine after the commit. However, commit 3cbc6123a93d ("mmc: sdhci: Set SDHCI_POWER_ON with external vmmc") sets the SDHCI_POWER_ON bit, this would make the host in marvell berlin SoCs won't work any more with external vmmc. This patch restores the behavior when setting VDD through external regulator by moving the call of mmc_regulator_set_ocr() to the end of sdhci_set_power() function. After this patch, the sdcard on Marvell Berlin SoC boards work again. Signed-off-by: Jisheng Zhang <jszhang@marvell.com> Fixes: 52221610dd84 ("mmc: sdhci: Improve external VDD ...") Reviewed-by: Ludovic Desroches <ludovic.desroches@atmel.com> Tested-by: Ludovic Desroches <ludovic.desroches@atmel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci.c19
1 files changed, 6 insertions, 13 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2753b722d1c9..d622435d1bcc 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1275,19 +1275,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
1275 struct mmc_host *mmc = host->mmc; 1275 struct mmc_host *mmc = host->mmc;
1276 u8 pwr = 0; 1276 u8 pwr = 0;
1277 1277
1278 if (!IS_ERR(mmc->supply.vmmc)) {
1279 spin_unlock_irq(&host->lock);
1280 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
1281 spin_lock_irq(&host->lock);
1282
1283 if (mode != MMC_POWER_OFF)
1284 sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
1285 else
1286 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
1287
1288 return;
1289 }
1290
1291 if (mode != MMC_POWER_OFF) { 1278 if (mode != MMC_POWER_OFF) {
1292 switch (1 << vdd) { 1279 switch (1 << vdd) {
1293 case MMC_VDD_165_195: 1280 case MMC_VDD_165_195:
@@ -1348,6 +1335,12 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
1348 if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) 1335 if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
1349 mdelay(10); 1336 mdelay(10);
1350 } 1337 }
1338
1339 if (!IS_ERR(mmc->supply.vmmc)) {
1340 spin_unlock_irq(&host->lock);
1341 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
1342 spin_lock_irq(&host->lock);
1343 }
1351} 1344}
1352 1345
1353/*****************************************************************************\ 1346/*****************************************************************************\