diff options
-rw-r--r-- | drivers/mmc/core/sdio.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 3e1881ce08c3..c586b11a40b5 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -641,7 +641,11 @@ try_again: * to switch to 1.8V signaling level. No 1.8v signalling if * UHS mode is not enabled to maintain compatibility and some * systems that claim 1.8v signalling in fact do not support - * it. + * it. Per SDIO spec v3, section 3.1.2, if the voltage is already + * 1.8v, the card sets S18A to 0 in the R4 response. So it will + * fails to check rocr & R4_18V_PRESENT, but we still need to + * try to init uhs card. sdio_read_cccr will take over this task + * to make sure which speed mode should work. */ if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, @@ -653,9 +657,6 @@ try_again: } else if (err) { ocr &= ~R4_18V_PRESENT; } - err = 0; - } else { - ocr &= ~R4_18V_PRESENT; } /* @@ -717,11 +718,20 @@ try_again: else { #endif /* - * Read the common registers. + * Read the common registers. Note that we should try to + * validate whether UHS would work or not. */ err = sdio_read_cccr(card, ocr); - if (err) - goto remove; + if (err) { + mmc_sdio_resend_if_cond(host, card); + if (ocr & R4_18V_PRESENT) { + /* Retry init sequence, but without R4_18V_PRESENT. */ + retries = 0; + goto try_again; + } else { + goto remove; + } + } #ifdef CONFIG_MMC_EMBEDDED_SDIO } #endif |