summary refs log tree commit diff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2007-05-01 15:08:30 +0200
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 15:08:30 +0200
commit89a73cf52ba2ae4402c53487b71ec4475544f139 (patch)
tree9ac38faa312bb5127dee2381d6c0923fe94192b1 /drivers/mmc
parent1addfcdbe4b23a20f28a097c2469d9f0c21bef23 (diff)
downloadlinux-89a73cf52ba2ae4402c53487b71ec4475544f139.tar.gz
mmc: separate out reading EXT_CSD
Separate the reading and decoding of the EXT_CSD register with the
actions taken on it.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/mmc.c75
1 files changed, 35 insertions, 40 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c2e120b11bef..47449e870131 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -152,10 +152,9 @@ static void mmc_decode_csd(struct mmc_card *card)
 }
 
 /*
- * Read and decode extended CSD. Switch to high-speed and wide bus
- * if supported.
+ * Read and decode extended CSD.
  */
-static int mmc_process_ext_csd(struct mmc_card *card)
+static int mmc_read_ext_csd(struct mmc_card *card)
 {
 	int err;
 	u8 *ext_csd;
@@ -223,39 +222,6 @@ static int mmc_process_ext_csd(struct mmc_card *card)
 		goto out;
 	}
 
-	if (card->host->caps & MMC_CAP_MMC_HIGHSPEED) {
-		/* Activate highspeed support. */
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			EXT_CSD_HS_TIMING, 1);
-		if (err != MMC_ERR_NONE) {
-			printk(KERN_WARNING "%s: failed to switch "
-				"card to mmc v4 high-speed mode.\n",
-			       mmc_hostname(card->host));
-			err = MMC_ERR_NONE;
-			goto out;
-		}
-
-		mmc_card_set_highspeed(card);
-
-		mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
-	}
-
-	/* Check for host support for wide-bus modes. */
-	if (card->host->caps & MMC_CAP_4_BIT_DATA) {
-		/* Activate 4-bit support. */
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
-		if (err != MMC_ERR_NONE) {
-			printk(KERN_WARNING "%s: failed to switch "
-				"card to mmc v4 4-bit bus mode.\n",
-			       mmc_hostname(card->host));
-			err = MMC_ERR_NONE;
-			goto out;
-		}
-
-		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
-	}
-
 out:
 	kfree(ext_csd);
 
@@ -391,19 +357,35 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
 	mmc_decode_cid(card);
 
 	/*
-	 * Fetch and process extened CSD.
-	 * This will switch into high-speed and wide bus modes,
-	 * as available.
+	 * Select card, as all following commands rely on that.
 	 */
 	err = mmc_select_card(card);
 	if (err != MMC_ERR_NONE)
 		goto free_card;
 
-	err = mmc_process_ext_csd(card);
+	/*
+	 * Fetch and process extened CSD.
+	 */
+	err = mmc_read_ext_csd(card);
 	if (err != MMC_ERR_NONE)
 		goto free_card;
 
 	/*
+	 * Activate high speed (if supported)
+	 */
+	if ((card->ext_csd.hs_max_dtr != 0) &&
+		(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			EXT_CSD_HS_TIMING, 1);
+		if (err != MMC_ERR_NONE)
+			goto free_card;
+
+		mmc_card_set_highspeed(card);
+
+		mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+	}
+
+	/*
 	 * Compute bus speed.
 	 */
 	max_dtr = (unsigned int)-1;
@@ -417,6 +399,19 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
 
 	mmc_set_clock(host, max_dtr);
 
+	/*
+	 * Activate wide bus (if supported).
+	 */
+	if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
+		(host->caps & MMC_CAP_4_BIT_DATA)) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
+		if (err != MMC_ERR_NONE)
+			goto free_card;
+
+		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+	}
+
 	host->card = card;
 
 	mmc_release_host(host);