aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/sdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r--drivers/mmc/core/sdio.c20
1 files changed, 18 insertions, 2 deletions
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;
}