diff -u linux-2.6-mmc/drivers/mmc/mmc.c linux/drivers/mmc/mmc.c --- linux-2.6-mmc/drivers/mmc/mmc.c Mon Sep 20 10:23:16 2004 +++ linux/drivers/mmc/mmc.c Wed Sep 22 15:14:00 2004 @@ -451,11 +451,26 @@ } /* + * Tell attached cards to go to IDLE state + */ +static void mmc_idle_cards(struct mmc_host *host) +{ + struct mmc_command cmd; + + cmd.opcode = MMC_GO_IDLE_STATE; + cmd.arg = 0; + cmd.flags = MMC_RSP_NONE; + + mmc_wait_for_cmd(host, &cmd, 0); + + mmc_delay(1); +} + +/* * Apply power to the MMC stack. */ static void mmc_power_up(struct mmc_host *host) { - struct mmc_command cmd; int bit = fls(host->ocr_avail) - 1; host->ios.vdd = bit; @@ -470,12 +485,6 @@ host->ops->set_ios(host, &host->ios); mmc_delay(2); - - cmd.opcode = MMC_GO_IDLE_STATE; - cmd.arg = 0; - cmd.flags = MMC_RSP_NONE; - - mmc_wait_for_cmd(host, &cmd, 0); } static void mmc_power_off(struct mmc_host *host) @@ -647,12 +656,22 @@ u32 ocr; mmc_power_up(host); + mmc_idle_cards(host); err = mmc_send_op_cond(host, 0, &ocr); if (err != MMC_ERR_NONE) return; host->ocr = mmc_select_voltage(host, ocr); + + /* + * Since we're changing the OCR value, we seem to + * need to tell some cards to go back to the idle + * state. We wait 1ms to give cards time to + * respond. + */ + if (host->ocr) + mmc_idle_cards(host); } else { host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; host->ios.clock = host->f_min;