summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2017-05-08 23:52:04 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2017-06-20 10:30:10 +0200
commit52c8212d80b69d2197bb8506384b6e6a0aef7fb7 (patch)
tree386ccbf33e6ea6cf72719dda6e1914f074bf860d
parent773a9ef85f02f6a82f58244f33cb628ad1ecac21 (diff)
downloadop-kernel-dev-52c8212d80b69d2197bb8506384b6e6a0aef7fb7.zip
op-kernel-dev-52c8212d80b69d2197bb8506384b6e6a0aef7fb7.tar.gz
mmc: core: Don't do eMMC HW reset when resuming the eMMC card
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>
-rw-r--r--drivers/mmc/core/core.c2
-rw-r--r--drivers/mmc/core/mmc.c2
-rw-r--r--drivers/mmc/core/pwrseq_emmc.c2
3 files changed, 5 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 82c45dd..ad8caf4 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -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);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 2c87ded..e3b6bea 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -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);
}
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c
index adc9c0c..efb8a79 100644
--- a/drivers/mmc/core/pwrseq_emmc.c
+++ b/drivers/mmc/core/pwrseq_emmc.c
@@ -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)
OpenPOWER on IntegriCloud