diff options
| author | Wanhyeong Ryu <wryu@qti.qualcomm.com> | 2017-11-01 15:51:40 +0800 |
|---|---|---|
| committer | Veerabhadrarao Badiganti <vbadigan@codeaurora.org> | 2017-11-07 15:39:33 +0530 |
| commit | 63d7fc8afd7b7fd97db552cc6c145c930b9eea32 (patch) | |
| tree | 710c436e54459643cd2d5966cab9ce6ec4c4365d | |
| parent | 91da619c3a57a7abcfa421200fd8aff275890772 (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.c | 17 | ||||
| -rw-r--r-- | include/linux/mmc/core.h | 2 |
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 |
