summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWanhyeong Ryu <wryu@qti.qualcomm.com>2017-11-01 15:51:40 +0800
committerVeerabhadrarao Badiganti <vbadigan@codeaurora.org>2017-11-07 15:39:33 +0530
commit63d7fc8afd7b7fd97db552cc6c145c930b9eea32 (patch)
tree710c436e54459643cd2d5966cab9ce6ec4c4365d
parent91da619c3a57a7abcfa421200fd8aff275890772 (diff)
mmc: core: Return error if fallback to lower speed mode fails
If there are continuous data-CRC errors in higher speed modes (SDR104 mode), then driver fallbacks to lower speed mode. But if at all it fails to fallback to lower speed mode, then that error should be propagated to the caller so that caller will handle it appropriately. Without this change, sometime while processing card removal event, driver fails to detect card removal and treats card as present eventhough its removed. Change-Id: I89544d41c5b014eb9227ba33ef9ec1917b6793dc Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
-rw-r--r--drivers/mmc/core/core.c17
-rw-r--r--include/linux/mmc/core.h2
2 files changed, 12 insertions, 7 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 372f1fbbde4c..cfd56d9fa2ca 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -464,10 +464,11 @@ out:
}
EXPORT_SYMBOL(mmc_clk_update_freq);
-void mmc_recovery_fallback_lower_speed(struct mmc_host *host)
+int mmc_recovery_fallback_lower_speed(struct mmc_host *host)
{
+ int err = 0;
if (!host->card)
- return;
+ return -EINVAL;
if (host->sdr104_wa && mmc_card_sd(host->card) &&
(host->ios.timing == MMC_TIMING_UHS_SDR104) &&
@@ -475,9 +476,14 @@ void mmc_recovery_fallback_lower_speed(struct mmc_host *host)
pr_err("%s: %s: blocked SDR104, lower the bus-speed (SDR50 / DDR50)\n",
mmc_hostname(host), __func__);
mmc_host_clear_sdr104(host);
- mmc_hw_reset(host);
+ err = mmc_hw_reset(host);
host->card->sdr104_blocked = true;
}
+ if (err)
+ pr_err("%s: %s: Fallback to lower speed mode failed with err=%d\n",
+ mmc_hostname(host), __func__, err);
+
+ return err;
}
static int mmc_devfreq_set_target(struct device *dev,
@@ -545,7 +551,7 @@ static int mmc_devfreq_set_target(struct device *dev,
if (err && err != -EAGAIN) {
pr_err("%s: clock scale to %lu failed with error %d\n",
mmc_hostname(host), *freq, err);
- mmc_recovery_fallback_lower_speed(host);
+ err = mmc_recovery_fallback_lower_speed(host);
} else {
pr_debug("%s: clock change to %lu finished successfully (%s)\n",
mmc_hostname(host), *freq, current->comm);
@@ -4121,8 +4127,7 @@ int _mmc_detect_card_removed(struct mmc_host *host)
if (ret) {
if (host->ops->get_cd && host->ops->get_cd(host)) {
- mmc_recovery_fallback_lower_speed(host);
- ret = 0;
+ ret = mmc_recovery_fallback_lower_speed(host);
} else {
mmc_card_set_removed(host->card);
if (host->card->sdr104_blocked) {
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 08b3b8348fd7..862d8d1bae8f 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -224,7 +224,7 @@ extern void mmc_cmdq_clk_scaling_start_busy(struct mmc_host *host,
bool lock_needed);
extern void mmc_cmdq_clk_scaling_stop_busy(struct mmc_host *host,
bool lock_needed, bool is_cmdq_dcmd);
-extern void mmc_recovery_fallback_lower_speed(struct mmc_host *host);
+extern int mmc_recovery_fallback_lower_speed(struct mmc_host *host);
/**
* mmc_claim_host - exclusively claim a host