diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 9f4d3a2..134a02d 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -266,26 +266,36 @@ static int
 esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
 	uint	xfertyp;
-	uint	irqstat;
+	uint	irqstat = 0, mask;
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
 	volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+	int ret = 0, timeout;
+
+	esdhc_write32(&regs->irqstat, 0xffffffffU);
+
+	sync();
+
+	mask = PRSSTAT_CICHB | PRSSTAT_CIDHB;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
 	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
 		return 0;
+#else
+	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+		mask &= ~PRSSTAT_CIDHB;
 #endif
 
-	esdhc_write32(&regs->irqstat, -1);
-
-	sync();
-
 	/* Wait for the bus to be idle */
-	while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
-			(esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
-		;
-
-	while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
-		;
+	timeout = 1000;
+	while (esdhc_read32(&regs->prsstat) & mask) {
+		if (timeout == 0) {
+			printf("\nController never released inhibit bit(s).\n");
+			ret = COMM_ERR;
+			goto reset;
+		}
+		timeout--;
+		mdelay(1);
+	}
 
 	/* Wait at least 8 SD clock cycles before the next command */
 	/*
@@ -296,11 +306,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
 	/* Set up for a data transfer if we have one */
 	if (data) {
-		int err;
-
-		err = esdhc_setup_data(mmc, data);
-		if(err)
-			return err;
+		ret = esdhc_setup_data(mmc, data);
+		if (ret)
+			goto reset;
 	}
 
 	/* Figure out the transfer arguments */
@@ -325,43 +333,14 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
 	irqstat = esdhc_read32(&regs->irqstat);
 
-	/* Reset CMD and DATA portions on error */
-	if (irqstat & CMD_ERR) {
-		esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
-			      SYSCTL_RSTC);
-		while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
-			;
-
-		if (data) {
-			esdhc_write32(&regs->sysctl,
-				      esdhc_read32(&regs->sysctl) |
-				      SYSCTL_RSTD);
-			while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
-				;
-		}
+	if (irqstat & IRQSTAT_CTOE) {
+		ret = TIMEOUT;
+		goto reset;
 	}
 
-	if (irqstat & IRQSTAT_CTOE)
-		return TIMEOUT;
-
-	if (irqstat & CMD_ERR)
-		return COMM_ERR;
-
-	/* Workaround for ESDHC errata ENGcm03648 */
-	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
-		int timeout = 2500;
-
-		/* Poll on DATA0 line for cmd with busy signal for 250 ms */
-		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
-					PRSSTAT_DAT0)) {
-			udelay(100);
-			timeout--;
-		}
-
-		if (timeout <= 0) {
-			printf("Timeout waiting for DAT0 to go high!\n");
-			return TIMEOUT;
-		}
+	if (irqstat & CMD_ERR) {
+		ret = COMM_ERR;
+		goto reset;
 	}
 
 	/* Copy the response to the response buffer */
@@ -379,7 +358,20 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 	} else
 		cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
 
-	/* Wait until all of the blocks are transferred */
+	/*
+	 * At 50 Mhz SD_CLK period, the max busy timeout
+	 * value or data transfer time need was about
+	 * = 2^27 * SD_CLK period ~= 2.69 sec.
+	 * So wait max 10 sec for data transfer complete or busy
+	 * state release.
+	 */
+	timeout = 10000;
+
+	/*
+	 * eSDHC host V2.3 has response busy interrupt, so
+	 * we should wait for busy state to be released and data
+	 * was out of programing state before next command send.
+	 */
 	if (data) {
 #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
 		esdhc_pio_read_write(mmc, data);
@@ -387,20 +379,76 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 		do {
 			irqstat = esdhc_read32(&regs->irqstat);
 
-			if (irqstat & IRQSTAT_DTOE)
-				return TIMEOUT;
+			if (irqstat & IRQSTAT_DTOE) {
+				ret = TIMEOUT;
+				break;
+			}
 
-			if (irqstat & DATA_ERR)
-				return COMM_ERR;
-		} while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
+			if (irqstat & DATA_ERR) {
+				ret = COMM_ERR;
+				break;
+			}
+
+			if (timeout <= 0) {
+				ret = TIMEOUT;
+				break;
+			}
+			mdelay(1);
+			timeout--;
+		} while (((irqstat & DATA_COMPLETE) != DATA_COMPLETE) &&
+				(esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
 #endif
 		if (data->flags & MMC_DATA_READ)
 			check_and_invalidate_dcache_range(cmd, data);
 	}
 
-	esdhc_write32(&regs->irqstat, -1);
+	 /* Workaround for ESDHC errata ENGcm03648 */
+	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
+		int timeout = 5000;
+
+		/* Poll on DATA0 line for cmd with busy signal for 5 sec */
+		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
+					PRSSTAT_DAT0)) {
+			mdelay(1);
+			timeout--;
+		}
+
+		if (timeout <= 0) {
+			printf("\nTimeout waiting for DAT0 to go high!\n");
+			ret = TIMEOUT;
+			goto reset;
+		}
+	}
+
+	if (esdhc_read32(&regs->irqstat) & (DATA_ERR | CMD_ERR))
+		ret = COMM_ERR;
+
+	if (ret)
+		goto reset;
+
+	esdhc_write32(&regs->irqstat, 0xffffffffU);
 
 	return 0;
+
+reset:
+
+	/* Reset CMD and DATA portions on error */
+	esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
+			SYSCTL_RSTC);
+	while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
+		;
+
+	if (data || (cmd->resp_type & MMC_RSP_BUSY)) {
+		esdhc_write32(&regs->sysctl,
+				esdhc_read32(&regs->sysctl) |
+				SYSCTL_RSTD);
+		while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
+			;
+	}
+
+	esdhc_write32(&regs->irqstat, 0xffffffffU);
+
+	return ret;
 }
 
 static void set_sysctl(struct mmc *mmc, uint clock)
