Merge "mmc: block: cmdq discard should use softirq completion path" into msm-4.9
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 5a91f9c..2b4d193 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1873,13 +1873,12 @@
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
 	struct mmc_cmdq_req *cmdq_req = NULL;
-	struct mmc_host *host = card->host;
-	struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx;
 	unsigned int from, nr, arg;
 	int err = 0;
 
 	if (!mmc_can_erase(card)) {
 		err = -EOPNOTSUPP;
+		blk_end_request(req, err, blk_rq_bytes(req));
 		goto out;
 	}
 
@@ -1908,16 +1907,9 @@
 	}
 	err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg);
 clear_dcmd:
-	/* clear pending request */
-	if (cmdq_req) {
-		BUG_ON(!test_and_clear_bit(cmdq_req->tag,
-					   &ctx_info->active_reqs));
-		clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
-	}
+	mmc_host_clk_hold(card->host);
+	blk_complete_request(req);
 out:
-	blk_end_request(req, err, blk_rq_bytes(req));
-	wake_up(&ctx_info->wait);
-	mmc_put_card(card);
 	return err ? 1 : 0;
 }
 
@@ -1971,12 +1963,11 @@
 	struct mmc_card *card = md->queue.card;
 	struct mmc_cmdq_req *cmdq_req = NULL;
 	unsigned int from, nr, arg;
-	struct mmc_host *host = card->host;
-	struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx;
 	int err = 0;
 
 	if (!(mmc_can_secure_erase_trim(card))) {
 		err = -EOPNOTSUPP;
+		blk_end_request(req, err, blk_rq_bytes(req));
 		goto out;
 	}
 
@@ -2022,16 +2013,9 @@
 				MMC_SECURE_TRIM2_ARG);
 	}
 clear_dcmd:
-	/* clear pending request */
-	if (cmdq_req) {
-		BUG_ON(!test_and_clear_bit(cmdq_req->tag,
-					   &ctx_info->active_reqs));
-		clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
-	}
+	mmc_host_clk_hold(card->host);
+	blk_complete_request(req);
 out:
-	blk_end_request(req, err, blk_rq_bytes(req));
-	wake_up(&ctx_info->wait);
-	mmc_put_card(card);
 	return err ? 1 : 0;
 }
 
@@ -3459,6 +3443,19 @@
 	else
 		mrq->data->error = -ETIMEDOUT;
 
+	if (mrq->cmd && mrq->cmd->error) {
+		if (!(mrq->req->cmd_flags & REQ_PREFLUSH)) {
+			/*
+			 * Notify completion for non flush commands like
+			 * discard that wait for DCMD finish.
+			 */
+			set_bit(CMDQ_STATE_REQ_TIMED_OUT,
+					&ctx_info->curr_state);
+			complete(&mrq->completion);
+			return BLK_EH_NOT_HANDLED;
+		}
+	}
+
 	if (test_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state) ||
 		test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state))
 		return BLK_EH_NOT_HANDLED;
@@ -3519,14 +3516,6 @@
 	} else if (mrq->cmd && mrq->cmd->error) {
 		/* DCMD commands */
 		err = mrq->cmd->error;
-
-		/*
-		 * Notify completion for non flush commands like discard
-		 * that wait for DCMD finish.
-		 */
-		if (!(mrq->req->cmd_flags & REQ_PREFLUSH)) {
-			complete(&mrq->completion);
-		}
 	}
 
 reset: