summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2015-11-03 19:03:41 -0800
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-31 15:27:50 -0700
commit0c86067ea8daf55a6a5b7f136bc930f71a2bdf76 (patch)
treec2f325165c7810b32bf959d6d83b822d586e0443
parenteeff0e83b0c9f070cac9af5c5f76054f635ae987 (diff)
mmc: block: ensure CMDQ is empty before queuing cache flush
Some devices might stop responding to new commands if device cache flush is queued to host controller while host controller is still processing outstanding requests. To workaround this issue, we are making the cmdq thread to wait for all the oustanding requests to be finished before queuing cache flush command on host controller. Change-Id: I15387734f51ca4cadfc9e11270f14d8a0806a00f Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
-rw-r--r--drivers/mmc/card/block.c15
-rw-r--r--include/linux/mmc/card.h3
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index bfd877cdb6e2..6dad4673090f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3494,6 +3494,19 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
else
ret = mmc_blk_cmdq_issue_discard_rq(mq, req);
} else if (cmd_flags & REQ_FLUSH) {
+ if (card->quirks &
+ MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH) {
+ ret = wait_event_interruptible(
+ card->host->cmdq_ctx.queue_empty_wq,
+ (!card->host->cmdq_ctx.active_reqs));
+ if (ret) {
+ pr_err("%s: failed while waiting for the CMDQ to be empty %s err (%d)\n",
+ mmc_hostname(card->host),
+ __func__, ret);
+ BUG_ON(1);
+ }
+ }
+
ret = mmc_blk_cmdq_issue_flush_rq(mq, req);
} else {
ret = mmc_blk_cmdq_issue_rw_rq(mq, req);
@@ -3961,6 +3974,8 @@ static const struct mmc_fixup blk_fixups[] =
MMC_QUIRK_BLK_NO_CMD23),
MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_BLK_NO_CMD23),
+ MMC_FIXUP(CID_NAME_ANY, CID_MANFID_TOSHIBA, CID_OEMID_ANY,
+ add_quirk_mmc, MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH),
/*
* Some Micron MMC cards needs longer data read timeout than
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 6fba3afcc2fb..2574e8af91fe 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -388,6 +388,9 @@ struct mmc_card {
#define MMC_QUIRK_QCA9377_SETTINGS (1 << 16) /* QCA9377 card settings*/
+/* Make sure CMDQ is empty before queuing cache flush */
+#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH (1 << 17)
+
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
unsigned int pref_erase; /* in sectors */