mmc: core: Don't do eMMC HW reset when resuming the eMMC card
authorUlf Hansson <ulf.hansson@linaro.org>
Mon, 8 May 2017 21:52:04 +0000 (23:52 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 20 Jun 2017 08:30:10 +0000 (10:30 +0200)
In case if a pwrseq-emmc has been bound to the host, a call to
mmc_power_up() triggers an eMMC HW reset via the pwrseq_emmc's
->post_power_on() callback. This isn't really what we want, as
mmc_power_up() is called each time when resuming the card.

As a matter of fact, the current approach may also violate the eMMC spec,
as the involved delays managed in pwrseq_emmc assumes both VCC and VCCQ has
been turned on, which isn't the case for VCCQ, unless the regulator is
always on.

Fix this behaviour by aligning to the same procedure used when the mmc host
implements the ->hw_reset() callback and has the MMC_CAP_HW_RESET flag set.
In this way the eMMC HW reset is issued at card detection scan, to cope
with bogus bootloaders and in the error recovery path via the mmc specific
bus_ops->reset() callback.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
drivers/mmc/core/core.c
drivers/mmc/core/mmc.c
drivers/mmc/core/pwrseq_emmc.c

index 82c45ddfa2023cd2e6d69218fb3c232a9c14d680..ad8caf49c038a13bdf70ff96972c5ec1ca695175 100644 (file)
@@ -2597,6 +2597,8 @@ EXPORT_SYMBOL(mmc_set_blockcount);
 
 static void mmc_hw_reset_for_init(struct mmc_host *host)
 {
+       mmc_pwrseq_reset(host);
+
        if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
                return;
        host->ops->hw_reset(host);
index 2c87dede584110919e2191a32e0b838c0c8cfc59..e3b6bea98fac95b31f2ea9d1a2def9ed05e61599 100644 (file)
@@ -27,6 +27,7 @@
 #include "mmc_ops.h"
 #include "quirks.h"
 #include "sd_ops.h"
+#include "pwrseq.h"
 
 #define DEFAULT_CMD6_TIMEOUT_MS        500
 
@@ -2127,6 +2128,7 @@ static int mmc_reset(struct mmc_host *host)
        } else {
                /* Do a brute force power cycle */
                mmc_power_cycle(host, card->ocr);
+               mmc_pwrseq_reset(host);
        }
        return mmc_init_card(host, card->ocr, card);
 }
index adc9c0c614fb122c58c50fd13ac60a1bfd69a36c..efb8a7965dd4a98c2e9d3e651e742a5488620f80 100644 (file)
@@ -56,7 +56,7 @@ static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this,
 }
 
 static const struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = {
-       .post_power_on = mmc_pwrseq_emmc_reset,
+       .reset = mmc_pwrseq_emmc_reset,
 };
 
 static int mmc_pwrseq_emmc_probe(struct platform_device *pdev)