summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/core/core.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 843edbed3ac9..2e94974d4d14 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2767,6 +2767,30 @@ out:
return;
}
+static bool mmc_is_vaild_state_for_clk_scaling(struct mmc_host *host)
+{
+ struct mmc_card *card = host->card;
+ u32 status;
+ bool ret = false;
+
+ if (!card)
+ goto out;
+
+ if (mmc_send_status(card, &status)) {
+ pr_err("%s: Get card status fail\n", mmc_hostname(card->host));
+ goto out;
+ }
+
+ switch (R1_CURRENT_STATE(status)) {
+ case R1_STATE_TRAN:
+ ret = true;
+ break;
+ default:
+ break;
+ }
+out:
+ return ret;
+}
/**
* mmc_clk_scaling() - clock scaling decision algorithm
@@ -2839,6 +2863,10 @@ static void mmc_clk_scaling(struct mmc_host *host, bool from_wq)
if (!from_wq)
cancel_delayed_work_sync(
&host->clk_scaling.work);
+
+ if (!mmc_is_vaild_state_for_clk_scaling(host))
+ goto bypass_scaling;
+
err = host->bus_ops->change_bus_speed(host, &freq);
if (!err)
host->clk_scaling.curr_freq = freq;
@@ -2860,6 +2888,7 @@ static void mmc_clk_scaling(struct mmc_host *host, bool from_wq)
}
mmc_reset_clk_scale_stats(host);
+bypass_scaling:
host->clk_scaling.in_progress = false;
out:
return;