mmc: msm_sdcc: reset wait_for_auto_prog_done flag in case of an error

"wait_for_auto_prog_done" flag is set when CMD53, single block write
(CMD24) or pre-defined (prefixed with CMD23) multi block write
(CMD25) need to be sent to card. This flag tells the
msmsdcc_start_data() to set the AUTO_PROG_DONE bit in MCI_DATA_CTL
register. If AUTO_PROG_DONE bit is set, SDCC controller will raise
the PROG_DONE at the end of above mentioned write transfers
(command + data) and "wait_for_auto_prog_done" gets cleared at
the end of transfer.

But if we get the error during the command transfer phase itself,
there is a chance that "wait_for_auto_prog_done" remains set which
means it remains sticky during next SDCC transfer request as well.
And if next data transfer is data read operation, having this
"wait_for_auto_prog_done" flag set will not allow the transfer to
end which may cause SDCC driver to raise request timeout.

Following is one such error condition:
<6>[  667.001892] mmc1: CMD6: Request timeout
<6>[  667.004700] mmc1: SDCC PWR is ON
<6>[  667.007904] mmc1: SDCC clks are ON, MCLK rate=400000
<6>[  667.012848] mmc1: SDCC irq is enabled
<6>[  667.067633] mmc1: SPS mode: busy=0
<6>[  667.071020] mmc1: xfer_size=64, data_xfered=64, xfer_remain=0
<6>[  667.076758] mmc1: got_dataend=1, prog_enable=0,
			wait_for_auto_prog_done=1, got_auto_prog_done=0

This patch ensures that "wait_for_auto_prog_done" gets cleared even when
error is seen during command transfer phase itself.

CRs-fixed: 342901
Change-Id: I27f635775ca488826fb46995784b544772fd8e16
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 6a02f48..ff12eb1 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -342,9 +342,6 @@
 
 	BUG_ON(host->curr.data);
 
-	host->curr.mrq = NULL;
-	host->curr.cmd = NULL;
-
 	del_timer(&host->req_tout_timer);
 
 	if (mrq->data)
@@ -352,6 +349,9 @@
 	if (mrq->cmd->error == -ETIMEDOUT)
 		mdelay(5);
 
+	/* Clear current request information as current request has ended */
+	memset(&host->curr, 0, sizeof(struct msmsdcc_curr_req));
+
 	/*
 	 * Need to drop the host lock here; mmc_request_done may call
 	 * back into the driver...
@@ -511,10 +511,13 @@
 		msmsdcc_stop_data(host);
 		if (!mrq->data->stop || mrq->cmd->error ||
 			(mrq->sbc && !mrq->data->error)) {
-			host->curr.mrq = NULL;
-			host->curr.cmd = NULL;
 			mrq->data->bytes_xfered = host->curr.data_xfered;
 			del_timer(&host->req_tout_timer);
+			/*
+			 * Clear current request information as current
+			 * request has ended
+			 */
+			memset(&host->curr, 0, sizeof(struct msmsdcc_curr_req));
 			spin_unlock_irqrestore(&host->lock, flags);
 
 			mmc_request_done(host->mmc, mrq);
@@ -668,10 +671,13 @@
 		msmsdcc_stop_data(host);
 		if (!mrq->data->stop || mrq->cmd->error ||
 			(mrq->sbc && !mrq->data->error)) {
-			host->curr.mrq = NULL;
-			host->curr.cmd = NULL;
 			mrq->data->bytes_xfered = host->curr.data_xfered;
 			del_timer(&host->req_tout_timer);
+			/*
+			 * Clear current request information as current
+			 * request has ended
+			 */
+			memset(&host->curr, 0, sizeof(struct msmsdcc_curr_req));
 			spin_unlock_irqrestore(&host->lock, flags);
 
 			mmc_request_done(host->mmc, mrq);
@@ -1561,6 +1567,7 @@
 					host->curr.cmd = cmd;
 			} else {
 				host->prog_enable = 0;
+				host->curr.wait_for_auto_prog_done = 0;
 				if (host->dummy_52_needed)
 					host->dummy_52_needed = 0;
 				if (cmd->data && cmd->error)
@@ -3981,6 +3988,7 @@
 			}
 		} else {
 			host->prog_enable = 0;
+			host->curr.wait_for_auto_prog_done = 0;
 			msmsdcc_reset_and_restore(host);
 			msmsdcc_request_end(host, mrq);
 		}