From 3f2da751beb84861ba0a999aaea09e73f578022a Mon Sep 17 00:00:00 2001
From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date: Thu, 19 Mar 2015 07:44:02 -0500
Subject: [PATCH 01/12] mmc: Fix typo in MMC type checking macro

The version flag constant name used in IS_MMC macro is incorrect/undefined.

Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
---
 include/mmc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/mmc.h b/include/mmc.h
index 2ad0f19..a251531 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -61,7 +61,7 @@
 #define SD_DATA_4BIT	0x00040000
 
 #define IS_SD(x)	((x)->version & SD_VERSION_SD)
-#define IS_MMC(x)	((x)->version & SD_VERSION_MMC)
+#define IS_MMC(x)	((x)->version & MMC_VERSION_MMC)
 
 #define MMC_DATA_READ		1
 #define MMC_DATA_WRITE		2

From a626c8d418d5fd1f8429294e7efe3fa2e4ca90fe Mon Sep 17 00:00:00 2001
From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date: Thu, 19 Mar 2015 07:44:03 -0500
Subject: [PATCH 02/12] mmc: Avoid extra duplicate entry in mmc device
 structure

The 'op_cond_response' field in mmc structure contains the response
from the last SEND_OP_COND MMC command while making iterational
polling of the card. Later it is copied to 'ocr' field, designed
to contain the OCR register value, which is actually the same
response from the same command. So, these fields have actually
the same data, just in different time periods. It's easier to use
the same 'ocr' field in both cases at once, without temporary using
of the 'op_cond_response' field.

Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
---
 drivers/mmc/mmc.c | 13 +++++++------
 include/mmc.h     |  1 -
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a13769e..fe00a19 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -362,8 +362,8 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
 	if (use_arg && !mmc_host_is_spi(mmc)) {
 		cmd->cmdarg =
 			(mmc->cfg->voltages &
-			(mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
-			(mmc->op_cond_response & OCR_ACCESS_MODE);
+			(mmc->ocr & OCR_VOLTAGE_MASK)) |
+			(mmc->ocr & OCR_ACCESS_MODE);
 
 		if (mmc->cfg->host_caps & MMC_MODE_HC)
 			cmd->cmdarg |= OCR_HCS;
@@ -371,7 +371,7 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
 	err = mmc_send_cmd(mmc, cmd, NULL);
 	if (err)
 		return err;
-	mmc->op_cond_response = cmd->response[0];
+	mmc->ocr = cmd->response[0];
 	return 0;
 }
 
@@ -391,7 +391,7 @@ static int mmc_send_op_cond(struct mmc *mmc)
 			return err;
 
 		/* exit if not busy (flag seems to be inverted) */
-		if (mmc->op_cond_response & OCR_BUSY)
+		if (mmc->ocr & OCR_BUSY)
 			return 0;
 	}
 	return IN_PROGRESS;
@@ -413,7 +413,7 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 		if (get_timer(start) > timeout)
 			return UNUSABLE_ERR;
 		udelay(100);
-	} while (!(mmc->op_cond_response & OCR_BUSY));
+	} while (!(mmc->ocr & OCR_BUSY));
 
 	if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
 		cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
@@ -424,10 +424,11 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 
 		if (err)
 			return err;
+
+		mmc->ocr = cmd.response[0];
 	}
 
 	mmc->version = MMC_VERSION_UNKNOWN;
-	mmc->ocr = cmd.response[0];
 
 	mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
 	mmc->rca = 1;
diff --git a/include/mmc.h b/include/mmc.h
index a251531..644e3fa 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -356,7 +356,6 @@ struct mmc {
 	char op_cond_pending;	/* 1 if we are waiting on an op_cond command */
 	char init_in_progress;	/* 1 if we have done mmc_start_init() */
 	char preinit;		/* start init as early as possible */
-	uint op_cond_response;	/* the response byte from the last op_cond */
 	int ddr_mode;
 };
 

From 5289b5350ba5442cfcfbb18488b3a9d9e4f39ede Mon Sep 17 00:00:00 2001
From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date: Thu, 19 Mar 2015 07:44:04 -0500
Subject: [PATCH 03/12] mmc: Do not pass external mmc_cmd structure to
 mmc_send_op_cond_iter()

The previous change to use 'ocr' structure field for storing send_op_cond
command response also stopped using command response directly
outside of mmc_send_op_cond_iter(). Now it becomes possible to use
command structure in mmc_send_op_cond_iter() locally, removing a necessity
to pass it as an argument from the caller.

Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
---
 drivers/mmc/mmc.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index fe00a19..d073d79 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -350,34 +350,32 @@ static int sd_send_op_cond(struct mmc *mmc)
 	return 0;
 }
 
-/* We pass in the cmd since otherwise the init seems to fail */
-static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
-		int use_arg)
+static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
 {
+	struct mmc_cmd cmd;
 	int err;
 
-	cmd->cmdidx = MMC_CMD_SEND_OP_COND;
-	cmd->resp_type = MMC_RSP_R3;
-	cmd->cmdarg = 0;
+	cmd.cmdidx = MMC_CMD_SEND_OP_COND;
+	cmd.resp_type = MMC_RSP_R3;
+	cmd.cmdarg = 0;
 	if (use_arg && !mmc_host_is_spi(mmc)) {
-		cmd->cmdarg =
+		cmd.cmdarg =
 			(mmc->cfg->voltages &
 			(mmc->ocr & OCR_VOLTAGE_MASK)) |
 			(mmc->ocr & OCR_ACCESS_MODE);
 
 		if (mmc->cfg->host_caps & MMC_MODE_HC)
-			cmd->cmdarg |= OCR_HCS;
+			cmd.cmdarg |= OCR_HCS;
 	}
-	err = mmc_send_cmd(mmc, cmd, NULL);
+	err = mmc_send_cmd(mmc, &cmd, NULL);
 	if (err)
 		return err;
-	mmc->ocr = cmd->response[0];
+	mmc->ocr = cmd.response[0];
 	return 0;
 }
 
 static int mmc_send_op_cond(struct mmc *mmc)
 {
-	struct mmc_cmd cmd;
 	int err, i;
 
 	/* Some cards seem to need this */
@@ -386,7 +384,7 @@ static int mmc_send_op_cond(struct mmc *mmc)
  	/* Asking to the card its capabilities */
 	mmc->op_cond_pending = 1;
 	for (i = 0; i < 2; i++) {
-		err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
+		err = mmc_send_op_cond_iter(mmc, i != 0);
 		if (err)
 			return err;
 
@@ -407,7 +405,7 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 	mmc->op_cond_pending = 0;
 	start = get_timer(0);
 	do {
-		err = mmc_send_op_cond_iter(mmc, &cmd, 1);
+		err = mmc_send_op_cond_iter(mmc, 1);
 		if (err)
 			return err;
 		if (get_timer(start) > timeout)

From cc17c01f2d3b691ddadbd46727d5f22db0a90808 Mon Sep 17 00:00:00 2001
From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date: Thu, 19 Mar 2015 07:44:05 -0500
Subject: [PATCH 04/12] mmc: Continue polling MMC card for OCR only if it is
 still not ready

Some MMC cards come to ready state quite quickly, so that the respective
flag appears to be set in mmc_send_op_cond already. In this case trying
to continue polling the card with CMD1 in mmc_complete_op_cond is incorrect
and may lead to unpredictable results. So check the flag before polling
and skip it appropriately.

Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
---
 drivers/mmc/mmc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d073d79..42af47c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -403,15 +403,17 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 	int err;
 
 	mmc->op_cond_pending = 0;
-	start = get_timer(0);
-	do {
-		err = mmc_send_op_cond_iter(mmc, 1);
-		if (err)
-			return err;
-		if (get_timer(start) > timeout)
-			return UNUSABLE_ERR;
-		udelay(100);
-	} while (!(mmc->ocr & OCR_BUSY));
+	if (!(mmc->ocr & OCR_BUSY)) {
+		start = get_timer(0);
+		do {
+			err = mmc_send_op_cond_iter(mmc, 1);
+			if (err)
+				return err;
+			if (get_timer(start) > timeout)
+				return UNUSABLE_ERR;
+			udelay(100);
+		} while (!(mmc->ocr & OCR_BUSY));
+	}
 
 	if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
 		cmd.cmdidx = MMC_CMD_SPI_READ_OCR;

From 1677eef45976da1cdccc73cd4291877dbb05eea9 Mon Sep 17 00:00:00 2001
From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date: Thu, 19 Mar 2015 07:44:06 -0500
Subject: [PATCH 05/12] mmc: Restructure polling loops to avoid extra delays

The polling loops in sd_send_op_cond and mmc_complete_op_cond functions
check the ready flag state at the end of the loop, that is after executing
a delay inside the loop, which, in case of exiting with no error,
is not needed. Also, one of these loops, as well as the loop
in mmc_send_status, have the delay just before exiting on timeout
conditions.

Restructure all these loops to check the respective conditions before making
a delay for the next loop pass, and to appropriately exit without the delay.

Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
---
 drivers/mmc/mmc.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 42af47c..b81533c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -118,7 +118,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
 	if (!mmc_host_is_spi(mmc))
 		cmd.cmdarg = mmc->rca << 16;
 
-	do {
+	while (1) {
 		err = mmc_send_cmd(mmc, &cmd, NULL);
 		if (!err) {
 			if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
@@ -135,9 +135,11 @@ int mmc_send_status(struct mmc *mmc, int timeout)
 		} else if (--retries < 0)
 			return err;
 
-		udelay(1000);
+		if (timeout-- <= 0)
+			break;
 
-	} while (timeout--);
+		udelay(1000);
+	}
 
 #ifdef CONFIG_MMC_TRACE
 	status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
@@ -291,7 +293,7 @@ static int sd_send_op_cond(struct mmc *mmc)
 	int err;
 	struct mmc_cmd cmd;
 
-	do {
+	while (1) {
 		cmd.cmdidx = MMC_CMD_APP_CMD;
 		cmd.resp_type = MMC_RSP_R1;
 		cmd.cmdarg = 0;
@@ -322,11 +324,14 @@ static int sd_send_op_cond(struct mmc *mmc)
 		if (err)
 			return err;
 
-		udelay(1000);
-	} while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+		if (cmd.response[0] & OCR_BUSY)
+			break;
 
-	if (timeout <= 0)
-		return UNUSABLE_ERR;
+		if (timeout-- <= 0)
+			return UNUSABLE_ERR;
+
+		udelay(1000);
+	}
 
 	if (mmc->version != SD_VERSION_2)
 		mmc->version = SD_VERSION_1_0;
@@ -405,14 +410,16 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 	mmc->op_cond_pending = 0;
 	if (!(mmc->ocr & OCR_BUSY)) {
 		start = get_timer(0);
-		do {
+		while (1) {
 			err = mmc_send_op_cond_iter(mmc, 1);
 			if (err)
 				return err;
+			if (mmc->ocr & OCR_BUSY)
+				break;
 			if (get_timer(start) > timeout)
 				return UNUSABLE_ERR;
 			udelay(100);
-		} while (!(mmc->ocr & OCR_BUSY));
+		}
 	}
 
 	if (mmc_host_is_spi(mmc)) { /* read OCR for spi */

From bd47c13583f2c4bbd29914063d2bf3a98fcdf5cb Mon Sep 17 00:00:00 2001
From: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date: Thu, 19 Mar 2015 07:44:07 -0500
Subject: [PATCH 06/12] mmc: Fix splitting device initialization

Starting part of device initialization sets the init_in_progress flag
only if the MMC card did not yet come to ready state and needs to continue
polling. If the card is SD or if the MMC card became ready quickly,
the flag is not set and (if using pre-initialization) the starting
phase will be re-executed from mmc_init function.

Set the init_in_progress flag in all non-error cases. Also, move flags
setting statements around so that the flags are not set in error paths.
Also, IN_PROGRESS return status becomes unnecessary, so get rid of it.

Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
---
 drivers/mmc/mmc.c | 16 ++++++++--------
 include/mmc.h     |  3 +--
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b81533c..31f8647 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -387,7 +387,6 @@ static int mmc_send_op_cond(struct mmc *mmc)
 	mmc_go_idle(mmc);
 
  	/* Asking to the card its capabilities */
-	mmc->op_cond_pending = 1;
 	for (i = 0; i < 2; i++) {
 		err = mmc_send_op_cond_iter(mmc, i != 0);
 		if (err)
@@ -395,9 +394,10 @@ static int mmc_send_op_cond(struct mmc *mmc)
 
 		/* exit if not busy (flag seems to be inverted) */
 		if (mmc->ocr & OCR_BUSY)
-			return 0;
+			break;
 	}
-	return IN_PROGRESS;
+	mmc->op_cond_pending = 1;
+	return 0;
 }
 
 static int mmc_complete_op_cond(struct mmc *mmc)
@@ -1627,7 +1627,7 @@ int mmc_start_init(struct mmc *mmc)
 	if (err == TIMEOUT) {
 		err = mmc_send_op_cond(mmc);
 
-		if (err && err != IN_PROGRESS) {
+		if (err) {
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 			printf("Card did not respond to voltage select!\n");
 #endif
@@ -1635,7 +1635,7 @@ int mmc_start_init(struct mmc *mmc)
 		}
 	}
 
-	if (err == IN_PROGRESS)
+	if (!err)
 		mmc->init_in_progress = 1;
 
 	return err;
@@ -1645,6 +1645,7 @@ static int mmc_complete_init(struct mmc *mmc)
 {
 	int err = 0;
 
+	mmc->init_in_progress = 0;
 	if (mmc->op_cond_pending)
 		err = mmc_complete_op_cond(mmc);
 
@@ -1654,13 +1655,12 @@ static int mmc_complete_init(struct mmc *mmc)
 		mmc->has_init = 0;
 	else
 		mmc->has_init = 1;
-	mmc->init_in_progress = 0;
 	return err;
 }
 
 int mmc_init(struct mmc *mmc)
 {
-	int err = IN_PROGRESS;
+	int err = 0;
 	unsigned start;
 
 	if (mmc->has_init)
@@ -1671,7 +1671,7 @@ int mmc_init(struct mmc *mmc)
 	if (!mmc->init_in_progress)
 		err = mmc_start_init(mmc);
 
-	if (!err || err == IN_PROGRESS)
+	if (!err)
 		err = mmc_complete_init(mmc);
 	debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
 	return err;
diff --git a/include/mmc.h b/include/mmc.h
index 644e3fa..fbcbe35 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -70,8 +70,7 @@
 #define UNUSABLE_ERR		-17 /* Unusable Card */
 #define COMM_ERR		-18 /* Communications Error */
 #define TIMEOUT			-19
-#define IN_PROGRESS		-20 /* operation is in progress */
-#define SWITCH_ERR		-21 /* Card reports failure to switch mode */
+#define SWITCH_ERR		-20 /* Card reports failure to switch mode */
 
 #define MMC_CMD_GO_IDLE_STATE		0
 #define MMC_CMD_SEND_OP_COND		1

From 5a20397b007e9c1482997cf4418639e9ba3df5fe Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Mon, 23 Mar 2015 17:56:59 -0500
Subject: [PATCH 07/12] mmc: remove the MMC_MODE_HC flag

High capacity support is not a host capability, but a device capability
that is queried via the OCR. The flag in the operating conditions
request argument can just be set unconditionally. This matches the Linux
implementation.

[panto] Hand merged and renumbering MMC_MODE_DDR_52MHz.

Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/mmc/dw_mmc.c     | 2 +-
 drivers/mmc/fsl_esdhc.c  | 2 +-
 drivers/mmc/kona_sdhci.c | 1 -
 drivers/mmc/mmc.c        | 7 ++-----
 drivers/mmc/mvebu_mmc.c  | 2 +-
 drivers/mmc/mxsmmc.c     | 3 +--
 drivers/mmc/omap_hsmmc.c | 3 +--
 drivers/mmc/s3c_sdi.c    | 2 +-
 drivers/mmc/s5p_sdhci.c  | 1 -
 drivers/mmc/sh_mmcif.c   | 2 +-
 drivers/mmc/sunxi_mmc.c  | 2 +-
 drivers/mmc/tegra_mmc.c  | 2 +-
 drivers/mmc/zynq_sdhci.c | 2 --
 include/mmc.h            | 3 +--
 14 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 76fa0b0..53a8aca 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -388,7 +388,7 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
 		host->cfg.host_caps |= MMC_MODE_4BIT;
 		host->cfg.host_caps &= ~MMC_MODE_8BIT;
 	}
-	host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
+	host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
 
 	host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 10ec216..2bbacb3 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -652,7 +652,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
 		return -1;
 	}
 
-	cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+	cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
 #ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
 	cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
 #endif
diff --git a/drivers/mmc/kona_sdhci.c b/drivers/mmc/kona_sdhci.c
index f804f4c..3653d00 100644
--- a/drivers/mmc/kona_sdhci.c
+++ b/drivers/mmc/kona_sdhci.c
@@ -121,7 +121,6 @@ int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
 	host->name = "kona-sdhci";
 	host->ioaddr = reg_base;
 	host->quirks = quirks;
-	host->host_caps = MMC_MODE_HC;
 
 	if (init_kona_mmc_core(host)) {
 		free(host);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 31f8647..3909e14 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -363,15 +363,12 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
 	cmd.cmdidx = MMC_CMD_SEND_OP_COND;
 	cmd.resp_type = MMC_RSP_R3;
 	cmd.cmdarg = 0;
-	if (use_arg && !mmc_host_is_spi(mmc)) {
-		cmd.cmdarg =
+	if (use_arg && !mmc_host_is_spi(mmc))
+		cmd.cmdarg = OCR_HCS |
 			(mmc->cfg->voltages &
 			(mmc->ocr & OCR_VOLTAGE_MASK)) |
 			(mmc->ocr & OCR_ACCESS_MODE);
 
-		if (mmc->cfg->host_caps & MMC_MODE_HC)
-			cmd.cmdarg |= OCR_HCS;
-	}
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 	if (err)
 		return err;
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
index 8ca0904..056aef5 100644
--- a/drivers/mmc/mvebu_mmc.c
+++ b/drivers/mmc/mvebu_mmc.c
@@ -418,7 +418,7 @@ static struct mmc_config mvebu_mmc_cfg = {
 	.f_min		= MVEBU_MMC_BASE_FAST_CLOCK / MVEBU_MMC_BASE_DIV_MAX,
 	.f_max		= MVEBU_MMC_CLOCKRATE_MAX,
 	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.host_caps	= MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HC |
+	.host_caps	= MMC_MODE_4BIT | MMC_MODE_HS |
 			  MMC_MODE_HS_52MHz,
 	.part_type	= PART_TYPE_DOS,
 	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index 2fa4eee..31fb3ab 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -405,8 +405,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
 	priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
 	priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
-			 MMC_MODE_HS_52MHz | MMC_MODE_HS |
-			 MMC_MODE_HC;
+			 MMC_MODE_HS_52MHz | MMC_MODE_HS;
 
 	/*
 	 * SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index dc725cb..8238a7e 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -651,8 +651,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 	if (priv_data == NULL)
 		return -1;
 
-	host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
-			     MMC_MODE_HC;
+	host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
 
 	switch (dev_index) {
 	case 0:
diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c
index 1b5b705..02d1138 100644
--- a/drivers/mmc/s3c_sdi.c
+++ b/drivers/mmc/s3c_sdi.c
@@ -298,7 +298,7 @@ int s3cmmc_initialize(bd_t *bis, int (*getcd)(struct mmc *),
 	cfg->name = "S3C MMC";
 	cfg->ops = &s3cmmc_ops;
 	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
-	cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HC | MMC_MODE_HS;
+	cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;
 	cfg->f_min = 400000;
 	cfg->f_max = get_PCLK() / 2;
 	cfg->b_max = 0x80;
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index 0eec731..8e1968a 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -76,7 +76,6 @@ static int s5p_sdhci_core_init(struct sdhci_host *host)
 	host->set_control_reg = &s5p_sdhci_set_control_reg;
 	host->set_clock = set_mmc_clk;
 
-	host->host_caps = MMC_MODE_HC;
 	if (host->bus_width == 8)
 		host->host_caps |= MMC_MODE_8BIT;
 
diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c
index 76ba93b..f92cf00 100644
--- a/drivers/mmc/sh_mmcif.c
+++ b/drivers/mmc/sh_mmcif.c
@@ -577,7 +577,7 @@ static struct mmc_config sh_mmcif_cfg = {
 	.name		= DRIVER_NAME,
 	.ops		= &sh_mmcif_ops,
 	.host_caps	= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
-			  MMC_MODE_8BIT | MMC_MODE_HC,
+			  MMC_MODE_8BIT,
 	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
 };
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 2233545..0b7eb12 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -449,7 +449,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
 
 	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 	cfg->host_caps = MMC_MODE_4BIT;
-	cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+	cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 	cfg->f_min = 400000;
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 2cd8cf1..ca41b4d 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -559,7 +559,7 @@ static int do_mmc_init(int dev_index)
 		host->cfg.host_caps |= MMC_MODE_8BIT;
 	if (host->width >= 4)
 		host->cfg.host_caps |= MMC_MODE_4BIT;
-	host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+	host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 
 	/*
 	 * min freq is for card identification, and is the highest
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index d4f3882..971acbb 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -29,8 +29,6 @@ int zynq_sdhci_init(phys_addr_t regbase)
 		       SDHCI_QUIRK_BROKEN_R1B;
 	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 
-	host->host_caps = MMC_MODE_HC;
-
 	add_sdhci(host, 52000000, 52000000 >> 9);
 	return 0;
 }
diff --git a/include/mmc.h b/include/mmc.h
index fbcbe35..dd98b3b 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -55,8 +55,7 @@
 #define MMC_MODE_4BIT		(1 << 2)
 #define MMC_MODE_8BIT		(1 << 3)
 #define MMC_MODE_SPI		(1 << 4)
-#define MMC_MODE_HC		(1 << 5)
-#define MMC_MODE_DDR_52MHz	(1 << 6)
+#define MMC_MODE_DDR_52MHz	(1 << 5)
 
 #define SD_DATA_4BIT	0x00040000
 

From 5e1c23cd392f17be9d135e504d48925a1cd92aa2 Mon Sep 17 00:00:00 2001
From: Kevin Liu <kliu5@marvell.com>
Date: Mon, 23 Mar 2015 17:57:00 -0500
Subject: [PATCH 08/12] mmc: sdhci: add timeout setting for response busy
 command

Timeout interrupt also work for response busy command(R1b) like
cmd38/cmd6. So need to set it accordingly. Current code only
set timeout for data command.

Signed-off-by: Kevin Liu <kliu5@marvell.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
---
 drivers/mmc/sdhci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 5332e61..75556a3 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -213,6 +213,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 				SDHCI_BLOCK_SIZE);
 		sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
 		sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
+	} else if (cmd->resp_type & MMC_RSP_BUSY) {
+		sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
 	}
 
 	sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);

From 253d5bdd64504a1a569b4eb330555e2449fa3d3f Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@freescale.com>
Date: Wed, 15 Apr 2015 10:13:12 +0800
Subject: [PATCH 09/12] mmc: fsl_esdhc: update eMMC44 adapter card erase
 timeout

Freescale eMMC44 adapter card uses Micron N2M400FDB311A3CF eMMC
memory. According to the silicon datasheet, secure erase timeout
is 600ms. So increase erase timeout value from 250ms to 600ms.

Signed-off-by: Yangbo Lu <yangbo.lu@freescale.com>
Cc: York Sun <yorksun@freescale.com>
---
 drivers/mmc/fsl_esdhc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 2bbacb3..b9bc165 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -387,9 +387,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
 	/* Workaround for ESDHC errata ENGcm03648 */
 	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
-		int timeout = 2500;
+		int timeout = 6000;
 
-		/* Poll on DATA0 line for cmd with busy signal for 250 ms */
+		/* Poll on DATA0 line for cmd with busy signal for 600 ms */
 		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
 					PRSSTAT_DAT0)) {
 			udelay(100);

From ebe78bb993423851b947b1e00f76c835c23e29b5 Mon Sep 17 00:00:00 2001
From: Alexander Stein <alexanders83@web.de>
Date: Fri, 17 Apr 2015 17:33:17 +0200
Subject: [PATCH 10/12] mmc: bcm2835_sdhci: Use calloc to allocate
 bcm2835_sdhci_host

We need to clear the allocated memory explicitly as the included
struct sdhci_host has function pointers. Those are compared to NULL to
test if this (optional) feature is supported. Leaving them undefined let
u-boot jump to arbitrary memory.

Signed-off-by: Alexander Stein <alexanders83@web.de>
---
 drivers/mmc/bcm2835_sdhci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index 4ec2968..5677513 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -154,9 +154,9 @@ int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
 	struct bcm2835_sdhci_host *bcm_host;
 	struct sdhci_host *host;
 
-	bcm_host = malloc(sizeof(*bcm_host));
+	bcm_host = calloc(1, sizeof(*bcm_host));
 	if (!bcm_host) {
-		printf("sdhci_host malloc fail!\n");
+		printf("sdhci_host calloc fail!\n");
 		return 1;
 	}
 

From 707ac1ad17c09a952b366709d98a5f454cfab909 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Mon, 4 May 2015 11:31:16 -0600
Subject: [PATCH 11/12] tegra: mmc: Set the removable flag correctly

If the mmc device is non-removable (as indicated by the device tree), set
the flag so that users of the device know.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
---
 drivers/mmc/tegra_mmc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index ca41b4d..d555692 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -528,7 +528,7 @@ static const struct mmc_ops tegra_mmc_ops = {
 	.getcd		= tegra_mmc_getcd,
 };
 
-static int do_mmc_init(int dev_index)
+static int do_mmc_init(int dev_index, bool removable)
 {
 	struct mmc_host *host;
 	struct mmc *mmc;
@@ -573,6 +573,7 @@ static int do_mmc_init(int dev_index)
 	host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 	mmc = mmc_create(&host->cfg, host);
+	mmc->block_dev.removable = removable;
 	if (mmc == NULL)
 		return -1;
 
@@ -586,7 +587,8 @@ static int do_mmc_init(int dev_index)
  * @param node		Device index (0-3)
  * @param host		Structure to fill in (reg, width, mmc_id)
  */
-static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
+static int mmc_get_config(const void *blob, int node, struct mmc_host *host,
+			  bool *removablep)
 {
 	debug("%s: node = %d\n", __func__, node);
 
@@ -619,6 +621,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
 				   GPIOD_IS_IN);
 	gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
 				   &host->pwr_gpio, GPIOD_IS_OUT);
+	*removablep = !fdtdec_get_bool(blob, node, "non-removable");
 
 	debug("%s: found controller at %p, width = %d, periph_id = %d\n",
 		__func__, host->reg, host->width, host->mmc_id);
@@ -636,6 +639,7 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
 static int process_nodes(const void *blob, int node_list[], int count)
 {
 	struct mmc_host *host;
+	bool removable;
 	int i, node;
 
 	debug("%s: count = %d\n", __func__, count);
@@ -649,11 +653,11 @@ static int process_nodes(const void *blob, int node_list[], int count)
 		host = &mmc_host[i];
 		host->id = i;
 
-		if (mmc_get_config(blob, node, host)) {
+		if (mmc_get_config(blob, node, host, &removable)) {
 			printf("%s: failed to decode dev %d\n",	__func__, i);
 			return -1;
 		}
-		do_mmc_init(i);
+		do_mmc_init(i, removable);
 	}
 	return 0;
 }

From 33fe2fb8df01647f97a7bce96a1c7781a7f6d253 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Mon, 4 May 2015 22:54:36 +0200
Subject: [PATCH 12/12] ARM: mmc: bcm283x: Remove get_timer_us() from mmc
 driver

The get_timer_us() function is something which is no longer
existing in case we use generic timer framework, so replace
it with get_timer().

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Tyler Baker <tyler.baker@linaro.org>
---
 drivers/mmc/bcm2835_sdhci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index 5677513..078ef05 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -69,11 +69,11 @@ static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
 	 * (Which is just as well - otherwise we'd have to nobble the DMA engine
 	 * too)
 	 */
-	while (get_timer_us(bcm_host->last_write) < bcm_host->twoticks_delay)
+	while (get_timer(bcm_host->last_write) < bcm_host->twoticks_delay)
 		;
 
 	writel(val, host->ioaddr + reg);
-	bcm_host->last_write = get_timer_us(0);
+	bcm_host->last_write = get_timer(0);
 }
 
 static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)