From 4a897cf6aa31fbb9e81dab20ac5f73515499b89d Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Wed, 4 Feb 2015 17:59:23 +0200 Subject: [PATCH] mmc: quirks: add new quirk that allows Cache disable This change allows us to prevent cache enable for certain cards that have broken cache functionality. Change-Id: Iea3f8c8f4e5498a8742fa408a19e3e169d1fa8cb Signed-off-by: Talel Shenhar [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- drivers/mmc/core/core.c | 3 ++- drivers/mmc/core/mmc.c | 54 +++++++++++++++++++++++++++------------- include/linux/mmc/card.h | 1 + 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b0aacd2f78d8..23ee6dc61e09 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -3354,7 +3354,8 @@ int mmc_flush_cache(struct mmc_card *card) if (mmc_card_mmc(card) && (card->ext_csd.cache_size > 0) && - (card->ext_csd.cache_ctrl & 1)) { + (card->ext_csd.cache_ctrl & 1) && + (!(card->quirks & MMC_QUIRK_CACHE_DISABLE))) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_FLUSH_CACHE, 1, 0); if (err == -ETIMEDOUT) { diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 245cd173eb45..c0faf2bbc711 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1816,26 +1816,46 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * the existence of cache and it can be turned on. * If HPI is not supported then cache shouldn't be enabled. */ - if (card->ext_csd.cache_size > 0 && card->ext_csd.hpi_en) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_CACHE_CTRL, 1, - card->ext_csd.generic_cmd6_time); - if (err && err != -EBADMSG) { - pr_err("%s: %s: mmc_switch() for CACHE_CTRL fails %d\n", + if (card->ext_csd.cache_size > 0) { + if (card->ext_csd.hpi_en && + (!(card->quirks & MMC_QUIRK_CACHE_DISABLE))) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_CACHE_CTRL, 1, + card->ext_csd.generic_cmd6_time); + if (err && err != -EBADMSG) { + pr_err("%s: %s: fail on CACHE_CTRL ON %d\n", mmc_hostname(host), __func__, err); - goto free_card; - } + goto free_card; + } - /* - * Only if no error, cache is turned on successfully. - */ - if (err) { - pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", - mmc_hostname(card->host), err); - card->ext_csd.cache_ctrl = 0; - err = 0; + /* + * Only if no error, cache is turned on successfully. + */ + if (err) { + pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", + mmc_hostname(card->host), err); + card->ext_csd.cache_ctrl = 0; + err = 0; + } else { + card->ext_csd.cache_ctrl = 1; + } } else { - card->ext_csd.cache_ctrl = 1; + /* + * mmc standard doesn't say what is the card default + * value for EXT_CSD_CACHE_CTRL. + * Hence, cache may be enabled by default by + * card vendors. + * Thus, it is best to explicitly disable cache in case + * we want to avoid cache. + */ + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_CACHE_CTRL, 0, + card->ext_csd.generic_cmd6_time); + if (err) { + pr_err("%s: %s: fail on CACHE_CTRL OFF %d\n", + mmc_hostname(host), __func__, err); + goto free_card; + } } } diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4cab91c56616..c3e6fbfbcfab 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -308,6 +308,7 @@ struct mmc_card { #define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ #define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ /* broken due to HPI feature */ +#define MMC_QUIRK_CACHE_DISABLE (1 << 14) /* prevent cache enable */ unsigned int erase_size; /* erase size in sectors */