From 52d0974e36761fd1daf1eb02cfb2444a7b200087 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Tue, 6 Mar 2012 17:59:12 +0530 Subject: [PATCH] mmc: core: hs200 fixes This patch fixes following issues when HS200 is enabled: 1. If executing_tuning() host ops is called without mmc_host_clk_hold(), card clocks might get turned off (if MMC_CLK_GATING is enabled) while execute_tuning() is in progress. So this patch makes sure that execute_tuning() is called with mmc_host_clk_hold(). 2. If host timing mode is set to HS200 mode, there should not be any communication with the card until execute_tuning() is completed. But there is a chance that CMD6 might be sent to enable set HPI_EN (of HPI_MGMT field in EXT_CSD) before execute_tuning() is called. So this patch moves this operation after execute_tuning() is completed. Signed-off-by: Subhash Jadavani Reviewed-by: girish.shivananjappa@linaro.org Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6defddd795f6..d7d8a93c3503 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1046,22 +1046,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, } } - /* - * Enable HPI feature (if supported) - */ - if (card->ext_csd.hpi) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HPI_MGMT, 1, 0); - if (err && err != -EBADMSG) - goto free_card; - if (err) { - pr_warning("%s: Enabling HPI failed\n", - mmc_hostname(card->host)); - err = 0; - } else - card->ext_csd.hpi_en = 1; - } - /* * Compute bus speed. */ @@ -1111,9 +1095,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * 4. execute tuning for HS200 */ if ((host->caps2 & MMC_CAP2_HS200) && - card->host->ops->execute_tuning) + card->host->ops->execute_tuning) { + mmc_host_clk_hold(card->host); err = card->host->ops->execute_tuning(card->host, MMC_SEND_TUNING_BLOCK_HS200); + mmc_host_clk_release(card->host); + } if (err) { pr_warning("%s: tuning execution failed\n", mmc_hostname(card->host)); @@ -1232,6 +1219,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, } } + /* + * Enable HPI feature (if supported) + */ + if (card->ext_csd.hpi) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_HPI_MGMT, 1, + card->ext_csd.generic_cmd6_time); + if (err && err != -EBADMSG) + goto free_card; + if (err) { + pr_warning("%s: Enabling HPI failed\n", + mmc_hostname(card->host)); + err = 0; + } else + card->ext_csd.hpi_en = 1; + } + /* * If cache size is higher than 0, this indicates * the existence of cache and it can be turned on.