summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */