From 51aa66a58494f869f491eedda86c409c50536c14 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Tue, 4 Dec 2012 17:06:18 +0530 Subject: mmc: sdio: fix resume failure due to lack of CMD52 reset If SDIO keep power flag (MMC_PM_KEEP_POWER) is not set, card would be reinitialized during resume but as we are not resetting (CMD52 reset) the SDIO card during this reinitialization, card may fail to respond back to subsequent commands (CMD5 etc...). This change resets the card before the reinitialization of card during resume. Signed-off-by: Subhash Jadavani Acked-by: Ulf Hansson Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/mmc/core/sdio.c') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2273ce6b6c1a..34ad4c877c1f 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -937,10 +937,12 @@ static int mmc_sdio_resume(struct mmc_host *host) mmc_claim_host(host); /* No need to reinitialize powered-resumed nonremovable cards */ - if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) + if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { + sdio_reset(host); + mmc_go_idle(host); err = mmc_sdio_init_card(host, host->ocr, host->card, mmc_card_keep_power(host)); - else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { + } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { /* We may have switched to 1-bit mode during suspend */ err = sdio_enable_4bit_bus(host->card); if (err > 0) { -- cgit v1.2.3 From 41875e388401ad97c33252d5fa39d52e0b70ee9b Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Tue, 4 Dec 2012 17:06:19 +0530 Subject: mmc: sdio: Fix SDIO 3.0 UHS-I initialization sequence According to UHS-I initialization sequence for SDIO 3.0 cards, the host must set bit[24] (S18R) of OCR register during OCR handshake to know whether the SDIO card is capable of doing 1.8V I/O. Signed-off-by: Sujit Reddy Thumma Signed-off-by: Subhash Jadavani Reviewed-by: Johan Rudholm Reviewed-by: Ulf Hansson Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 22 +++++++++++----------- include/linux/mmc/host.h | 8 ++++++++ 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers/mmc/core/sdio.c') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 34ad4c877c1f..9565d38d91a4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -157,10 +157,7 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr) if (ret) goto out; - if (card->host->caps & - (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | - MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | - MMC_CAP_UHS_DDR50)) { + if (mmc_host_uhs(card->host)) { if (data & SDIO_UHS_DDR50) card->sw_caps.sd3_bus_mode |= SD_MODE_UHS_DDR50; @@ -478,8 +475,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) * If the host doesn't support any of the UHS-I modes, fallback on * default speed. */ - if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | - MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) + if (!mmc_host_uhs(card->host)) return 0; bus_speed = SDIO_SPEED_SDR12; @@ -645,11 +641,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, * systems that claim 1.8v signalling in fact do not support * it. */ - if ((ocr & R4_18V_PRESENT) && - (host->caps & - (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | - MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | - MMC_CAP_UHS_DDR50))) { + if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true); if (err) { @@ -1022,6 +1014,10 @@ static int mmc_sdio_power_restore(struct mmc_host *host) goto out; } + if (mmc_host_uhs(host)) + /* to query card if 1.8V signalling is supported */ + host->ocr |= R4_18V_PRESENT; + ret = mmc_sdio_init_card(host, host->ocr, host->card, mmc_card_keep_power(host)); if (!ret && host->sdio_irqs) @@ -1087,6 +1083,10 @@ int mmc_attach_sdio(struct mmc_host *host) /* * Detect and init the card. */ + if (mmc_host_uhs(host)) + /* to query card if 1.8V signalling is supported */ + host->ocr |= R4_18V_PRESENT; + err = mmc_sdio_init_card(host, host->ocr, NULL, 0); if (err) { if (err == -EAGAIN) { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 61a10c17aabd..c89a1bb87fa5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -434,6 +434,14 @@ static inline int mmc_boot_partition_access(struct mmc_host *host) return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); } +static inline int mmc_host_uhs(struct mmc_host *host) +{ + return host->caps & + (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | + MMC_CAP_UHS_DDR50); +} + #ifdef CONFIG_MMC_CLKGATE void mmc_host_clk_hold(struct mmc_host *host); void mmc_host_clk_release(struct mmc_host *host); -- cgit v1.2.3 From 77e2ff08925c7ec7267dc87c27eda2e62d585b57 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Tue, 4 Dec 2012 17:06:20 +0530 Subject: mmc: sdio: print correct UHS mode during card detection When SDIO3.0 card is detected, incorrect bus speed mode is printed as part of card detection print in kernel logs. This change fixes it so that user won't be confused by looking at incorrect card detection message in logs. Signed-off-by: Subhash Jadavani Tested-by: Jackey Shen Acked-by: Ulf Hansson Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/mmc/core/sdio.c') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 9565d38d91a4..3a64933466b8 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -485,23 +485,27 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) bus_speed = SDIO_SPEED_SDR104; timing = MMC_TIMING_UHS_SDR104; card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; + card->sd_bus_speed = UHS_SDR104_BUS_SPEED; } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { bus_speed = SDIO_SPEED_DDR50; timing = MMC_TIMING_UHS_DDR50; card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; + card->sd_bus_speed = UHS_DDR50_BUS_SPEED; } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50)) { bus_speed = SDIO_SPEED_SDR50; timing = MMC_TIMING_UHS_SDR50; card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; + card->sd_bus_speed = UHS_SDR50_BUS_SPEED; } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { bus_speed = SDIO_SPEED_SDR25; timing = MMC_TIMING_UHS_SDR25; card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; + card->sd_bus_speed = UHS_SDR25_BUS_SPEED; } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & @@ -509,6 +513,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) bus_speed = SDIO_SPEED_SDR12; timing = MMC_TIMING_UHS_SDR12; card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; + card->sd_bus_speed = UHS_SDR12_BUS_SPEED; } err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); -- cgit v1.2.3 From 567c89032cfdda8047562abe450947ac01f2d3c7 Mon Sep 17 00:00:00 2001 From: Johan Rudholm Date: Mon, 28 Jan 2013 15:08:27 +0100 Subject: mmc: core: Break out start_signal_voltage_switch Allow callers to access the start_signal_voltage_switch host_ops member without going through any cmd11 logic. This is mostly a preparation for the following signal voltage switch patch. Also, reset ios.signal_voltage to its original value if start_signal_voltage_switch fails. Signed-off-by: Johan Rudholm Acked-by: Ulf Hansson Tested-by: Wei WANG Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 35 +++++++++++++++++++++++------------ drivers/mmc/core/core.h | 4 ++-- drivers/mmc/core/mmc.c | 8 ++++---- drivers/mmc/core/sd.c | 2 +- drivers/mmc/core/sdio.c | 3 +-- 5 files changed, 31 insertions(+), 21 deletions(-) (limited to 'drivers/mmc/core/sdio.c') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 789056fbfc93..bb794c784597 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1317,7 +1317,26 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) return ocr; } -int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11) +int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) +{ + int err = 0; + int old_signal_voltage = host->ios.signal_voltage; + + host->ios.signal_voltage = signal_voltage; + if (host->ops->start_signal_voltage_switch) { + mmc_host_clk_hold(host); + err = host->ops->start_signal_voltage_switch(host, &host->ios); + mmc_host_clk_release(host); + } + + if (err) + host->ios.signal_voltage = old_signal_voltage; + + return err; + +} + +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) { struct mmc_command cmd = {0}; int err = 0; @@ -1328,7 +1347,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 * Send CMD11 only if the request is to switch the card to * 1.8V signalling. */ - if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) { + if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) { cmd.opcode = SD_SWITCH_VOLTAGE; cmd.arg = 0; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; @@ -1341,15 +1360,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 return -EIO; } - host->ios.signal_voltage = signal_voltage; - - if (host->ops->start_signal_voltage_switch) { - mmc_host_clk_hold(host); - err = host->ops->start_signal_voltage_switch(host, &host->ios); - mmc_host_clk_release(host); - } - - return err; + return __mmc_set_signal_voltage(host, signal_voltage); } /* @@ -1412,7 +1423,7 @@ static void mmc_power_up(struct mmc_host *host) mmc_set_ios(host); /* Set signal voltage to 3.3V */ - mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, false); + __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); /* * This delay should be sufficient to allow the power supply diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 9007de74d8a9..b9f18a2a8874 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -40,8 +40,8 @@ void mmc_set_ungated(struct mmc_host *host); void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); void mmc_set_bus_width(struct mmc_host *host, unsigned int width); u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); -int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, - bool cmd11); +int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); +int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); void mmc_set_timing(struct mmc_host *host, unsigned int timing); void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); void mmc_power_off(struct mmc_host *host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0d7a9795a6da..8a3ad602a877 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -769,11 +769,11 @@ static int mmc_select_hs200(struct mmc_card *card) if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V && host->caps2 & MMC_CAP2_HS200_1_2V_SDR) - err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0); + err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); if (err && card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_8V && host->caps2 & MMC_CAP2_HS200_1_8V_SDR) - err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, 0); + err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); /* If fails try again during next card power cycle */ if (err) @@ -1221,8 +1221,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * WARNING: eMMC rules are NOT the same as SD DDR */ if (ddr == MMC_1_2V_DDR_MODE) { - err = mmc_set_signal_voltage(host, - MMC_SIGNAL_VOLTAGE_120, 0); + err = __mmc_set_signal_voltage(host, + MMC_SIGNAL_VOLTAGE_120); if (err) goto err; } diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 937363948079..9a59fcd55a75 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -757,7 +757,7 @@ try_again: */ if (!mmc_host_is_spi(host) && rocr && ((*rocr & 0x41000000) == 0x41000000)) { - err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true); + err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); if (err) { ocr &= ~SD_OCR_S18R; goto try_again; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 3a64933466b8..1a726aef211d 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -647,8 +647,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, * it. */ if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { - err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, - true); + err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); if (err) { ocr &= ~R4_18V_PRESENT; host->ocr &= ~R4_18V_PRESENT; -- cgit v1.2.3 From 0797e5f1453b2bedc08bbcbea0ea4fbe20350823 Mon Sep 17 00:00:00 2001 From: Johan Rudholm Date: Mon, 28 Jan 2013 15:08:28 +0100 Subject: mmc: core: Fixup signal voltage switch When switching SD and SDIO cards from 3.3V to 1.8V signal levels, the clock should be gated for 5 ms during the step. After enabling the clock, the host should wait for at least 1 ms before checking for failure. Failure by the card to switch is indicated by dat[0:3] being pulled low. The host should check for this condition and power-cycle the card if failure is indicated. Add a retry mechanism for the SDIO case. If the voltage switch fails repeatedly, give up and continue the initialization using the original voltage. This patch places a couple of requirements on the host driver: 1) mmc_set_ios with ios.clock = 0 must gate the clock 2) mmc_power_off must actually cut the power to the card 3) The card_busy host_ops member must be implemented if these requirements are not fulfilled, the 1.8V signal voltage switch will still be attempted but may not be successful. Signed-off-by: Johan Rudholm Signed-off-by: Kevin Liu Acked-by: Ulf Hansson Tested-by: Wei WANG Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 83 +++++++++++++++++++++++++++++++++++++++++++------ drivers/mmc/core/sd.c | 21 ++++++++++--- drivers/mmc/core/sdio.c | 20 ++++++++++-- 3 files changed, 107 insertions(+), 17 deletions(-) (limited to 'drivers/mmc/core/sdio.c') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index bb794c784597..e41badbf9b50 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1340,6 +1340,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) { struct mmc_command cmd = {0}; int err = 0; + u32 clock; BUG_ON(!host); @@ -1347,20 +1348,82 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) * Send CMD11 only if the request is to switch the card to * 1.8V signalling. */ - if (signal_voltage != MMC_SIGNAL_VOLTAGE_330) { - cmd.opcode = SD_SWITCH_VOLTAGE; - cmd.arg = 0; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) + return __mmc_set_signal_voltage(host, signal_voltage); - err = mmc_wait_for_cmd(host, &cmd, 0); - if (err) - return err; + /* + * If we cannot switch voltages, return failure so the caller + * can continue without UHS mode + */ + if (!host->ops->start_signal_voltage_switch) + return -EPERM; + if (!host->ops->card_busy) + pr_warning("%s: cannot verify signal voltage switch\n", + mmc_hostname(host)); + + cmd.opcode = SD_SWITCH_VOLTAGE; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err) + return err; - if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) - return -EIO; + if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) + return -EIO; + + mmc_host_clk_hold(host); + /* + * The card should drive cmd and dat[0:3] low immediately + * after the response of cmd11, but wait 1 ms to be sure + */ + mmc_delay(1); + if (host->ops->card_busy && !host->ops->card_busy(host)) { + err = -EAGAIN; + goto power_cycle; } + /* + * During a signal voltage level switch, the clock must be gated + * for 5 ms according to the SD spec + */ + clock = host->ios.clock; + host->ios.clock = 0; + mmc_set_ios(host); - return __mmc_set_signal_voltage(host, signal_voltage); + if (__mmc_set_signal_voltage(host, signal_voltage)) { + /* + * Voltages may not have been switched, but we've already + * sent CMD11, so a power cycle is required anyway + */ + err = -EAGAIN; + goto power_cycle; + } + + /* Keep clock gated for at least 5 ms */ + mmc_delay(5); + host->ios.clock = clock; + mmc_set_ios(host); + + /* Wait for at least 1 ms according to spec */ + mmc_delay(1); + + /* + * Failure to switch is indicated by the card holding + * dat[0:3] low + */ + if (host->ops->card_busy && host->ops->card_busy(host)) + err = -EAGAIN; + +power_cycle: + if (err) { + pr_debug("%s: Signal voltage switch failed, " + "power cycling card\n", mmc_hostname(host)); + mmc_power_cycle(host); + } + + mmc_host_clk_release(host); + + return err; } /* diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 9a59fcd55a75..03134b1e563c 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -712,6 +712,14 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) { int err; u32 max_current; + int retries = 10; + +try_again: + if (!retries) { + ocr &= ~SD_OCR_S18R; + pr_warning("%s: Skipping voltage switch\n", + mmc_hostname(host)); + } /* * Since we're changing the OCR value, we seem to @@ -733,9 +741,10 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) /* * If the host supports one of UHS-I modes, request the card - * to switch to 1.8V signaling level. + * to switch to 1.8V signaling level. If the card has failed + * repeatedly to switch however, skip this. */ - if (mmc_host_uhs(host)) + if (retries && mmc_host_uhs(host)) ocr |= SD_OCR_S18R; /* @@ -746,7 +755,6 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) if (max_current > 150) ocr |= SD_OCR_XPC; -try_again: err = mmc_send_app_op_cond(host, ocr, rocr); if (err) return err; @@ -758,8 +766,11 @@ try_again: if (!mmc_host_is_spi(host) && rocr && ((*rocr & 0x41000000) == 0x41000000)) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); - if (err) { - ocr &= ~SD_OCR_S18R; + if (err == -EAGAIN) { + retries--; + goto try_again; + } else if (err) { + retries = 0; goto try_again; } } diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 1a726aef211d..aa0719a4dfd1 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -584,10 +584,19 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, { struct mmc_card *card; int err; + int retries = 10; BUG_ON(!host); WARN_ON(!host->claimed); +try_again: + if (!retries) { + pr_warning("%s: Skipping voltage switch\n", + mmc_hostname(host)); + ocr &= ~R4_18V_PRESENT; + host->ocr &= ~R4_18V_PRESENT; + } + /* * Inform the card of the voltage */ @@ -646,9 +655,16 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, * systems that claim 1.8v signalling in fact do not support * it. */ - if ((ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { + if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); - if (err) { + if (err == -EAGAIN) { + sdio_reset(host); + mmc_go_idle(host); + mmc_send_if_cond(host, host->ocr_avail); + mmc_remove_card(card); + retries--; + goto try_again; + } else if (err) { ocr &= ~R4_18V_PRESENT; host->ocr &= ~R4_18V_PRESENT; } -- cgit v1.2.3