summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2015-02-20 18:57:19 (GMT)
committerUlf Hansson <ulf.hansson@linaro.org>2015-03-23 13:13:30 (GMT)
commitd1f1dd86006c668aea2014b524b0d5e7bec3edca (patch)
treeb3bf5d52ee630b458ae28c8caf3616b7bc2d26aa /drivers/mmc
parent655babbde6fdbd5a4a4072b7cdd8b1fb1a23db24 (diff)
downloadlinux-d1f1dd86006c668aea2014b524b0d5e7bec3edca.tar.xz
mmc: dw_mmc: Give a good reset after we give power
We should give dw_mmc a good reset after we apply power. On some boards vqmmc may actually be connected to the IP block in the SoC so it's good to reset after power comes in. Without this we sometimes see failures enumerating cards on rk3288. Signed-off-by: Doug Anderson <dianders@chromium.org> Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/dw_mmc.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index a5315b2..d7fca9d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1120,13 +1120,23 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
mci_writel(slot->host, PWREN, regs);
break;
case MMC_POWER_ON:
- if (!IS_ERR(mmc->supply.vqmmc) && !slot->host->vqmmc_enabled) {
- ret = regulator_enable(mmc->supply.vqmmc);
- if (ret < 0)
- dev_err(slot->host->dev,
- "failed to enable vqmmc regulator\n");
- else
+ if (!slot->host->vqmmc_enabled) {
+ if (!IS_ERR(mmc->supply.vqmmc)) {
+ ret = regulator_enable(mmc->supply.vqmmc);
+ if (ret < 0)
+ dev_err(slot->host->dev,
+ "failed to enable vqmmc\n");
+ else
+ slot->host->vqmmc_enabled = true;
+
+ } else {
+ /* Keep track so we don't reset again */
slot->host->vqmmc_enabled = true;
+ }
+
+ /* Reset our state machine after powering on */
+ dw_mci_ctrl_reset(slot->host,
+ SDMMC_CTRL_ALL_RESET_FLAGS);
}
/* Adjust clock / bus width after power is up */
@@ -1140,10 +1150,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (!IS_ERR(mmc->supply.vmmc))
mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
- if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled) {
+ if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled)
regulator_disable(mmc->supply.vqmmc);
- slot->host->vqmmc_enabled = false;
- }
+ slot->host->vqmmc_enabled = false;
regs = mci_readl(slot->host, PWREN);
regs &= ~(1 << slot->id);