From fec8ffcb2b32902a07fb298453f254bebdc503d0 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Fri, 1 Feb 2013 17:14:33 +0530 Subject: mmc: core: run clock scaling only in valid card state Clock scaling requires the tuning and if the tuning command is sent to the card in invalid state, tuning procedure will fail. With urgent request mechanism implemented, there is a chance that clock scaling invoked when card is not in a proper state to receive the tuning command. This change checks the card state (by sending the status command) before invoking the clock scaling request. Change-Id: Icb71a8e74a9afdc70380a5901cd3d28931959e9c Signed-off-by: Subhash Jadavani --- drivers/mmc/core/core.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) 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; -- cgit v1.2.3