diff options
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r-- | drivers/mmc/core/sdio.c | 92 |
1 files changed, 37 insertions, 55 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 712a7742765e..8dd8fc32ecca 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -559,7 +559,7 @@ static void mmc_sdio_resend_if_cond(struct mmc_host *host, * we're trying to reinitialise. */ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, - struct mmc_card *oldcard, int powered_resume) + struct mmc_card *oldcard) { struct mmc_card *card; int err; @@ -582,11 +582,9 @@ try_again: /* * Inform the card of the voltage */ - if (!powered_resume) { - err = mmc_send_io_op_cond(host, ocr, &rocr); - if (err) - goto err; - } + err = mmc_send_io_op_cond(host, ocr, &rocr); + if (err) + goto err; /* * For SPI, enable CRC as appropriate. @@ -645,7 +643,7 @@ try_again: * 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)) { + if (rocr & ocr & R4_18V_PRESENT) { err = mmc_set_uhs_voltage(host, ocr_card); if (err == -EAGAIN) { mmc_sdio_resend_if_cond(host, card); @@ -659,7 +657,7 @@ try_again: /* * For native busses: set card RCA and quit open drain mode. */ - if (!powered_resume && !mmc_host_is_spi(host)) { + if (!mmc_host_is_spi(host)) { err = mmc_send_relative_addr(host, &card->rca); if (err) goto remove; @@ -687,7 +685,7 @@ try_again: /* * Select card, as all following commands rely on that. */ - if (!powered_resume && !mmc_host_is_spi(host)) { + if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto remove; @@ -816,10 +814,27 @@ err: return err; } -static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume) +static int mmc_sdio_reinit_card(struct mmc_host *host) { int ret; + /* + * Reset the card by performing the same steps that are taken by + * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. + * + * sdio_reset() is technically not needed. Having just powered up the + * hardware, it should already be in reset state. However, some + * platforms (such as SD8686 on OLPC) do not instantly cut power, + * meaning that a reset is required when restoring power soon after + * powering off. It is harmless in other cases. + * + * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec, + * is not necessary for non-removable cards. However, it is required + * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and + * harmless in other situations. + * + */ + sdio_reset(host); mmc_go_idle(host); mmc_send_if_cond(host, host->card->ocr); @@ -828,8 +843,7 @@ static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume) if (ret) return ret; - return mmc_sdio_init_card(host, host->card->ocr, host->card, - powered_resume); + return mmc_sdio_init_card(host, host->card->ocr, host->card); } /* @@ -965,7 +979,11 @@ static int mmc_sdio_resume(struct mmc_host *host) /* Basic card reinitialization. */ mmc_claim_host(host); - /* Restore power if needed */ + /* + * Restore power and reinitialize the card when needed. Note that a + * removable card is checked from a detect work later on in the resume + * process. + */ if (!mmc_card_keep_power(host)) { mmc_power_up(host, host->card->ocr); /* @@ -979,12 +997,8 @@ static int mmc_sdio_resume(struct mmc_host *host) pm_runtime_set_active(&host->card->dev); pm_runtime_enable(&host->card->dev); } - } - - /* No need to reinitialize powered-resumed nonremovable cards */ - if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { - err = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); - } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { + err = mmc_sdio_reinit_card(host); + } else if (mmc_card_wake_sdio_irq(host)) { /* We may have switched to 1-bit mode during suspend */ err = sdio_enable_4bit_bus(host->card); } @@ -1009,38 +1023,6 @@ out: return err; } -static int mmc_sdio_power_restore(struct mmc_host *host) -{ - int ret; - - /* - * Reset the card by performing the same steps that are taken by - * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. - * - * sdio_reset() is technically not needed. Having just powered up the - * hardware, it should already be in reset state. However, some - * platforms (such as SD8686 on OLPC) do not instantly cut power, - * meaning that a reset is required when restoring power soon after - * powering off. It is harmless in other cases. - * - * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec, - * is not necessary for non-removable cards. However, it is required - * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and - * harmless in other situations. - * - */ - - mmc_claim_host(host); - - ret = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); - if (!ret && host->sdio_irqs) - mmc_signal_sdio_irq(host); - - mmc_release_host(host); - - return ret; -} - static int mmc_sdio_runtime_suspend(struct mmc_host *host) { /* No references to the card, cut the power to it. */ @@ -1058,7 +1040,7 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) /* Restore power and re-initialize. */ mmc_claim_host(host); mmc_power_up(host, host->card->ocr); - ret = mmc_sdio_power_restore(host); + ret = mmc_sdio_reinit_card(host); mmc_release_host(host); return ret; @@ -1067,7 +1049,7 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) static int mmc_sdio_hw_reset(struct mmc_host *host) { mmc_power_cycle(host, host->card->ocr); - return mmc_sdio_power_restore(host); + return mmc_sdio_reinit_card(host); } static int mmc_sdio_sw_reset(struct mmc_host *host) @@ -1079,7 +1061,7 @@ static int mmc_sdio_sw_reset(struct mmc_host *host) mmc_set_initial_state(host); mmc_set_initial_signal_voltage(host); - return mmc_sdio_reinit_card(host, 0); + return mmc_sdio_reinit_card(host); } static const struct mmc_bus_ops mmc_sdio_ops = { @@ -1129,7 +1111,7 @@ int mmc_attach_sdio(struct mmc_host *host) /* * Detect and init the card. */ - err = mmc_sdio_init_card(host, rocr, NULL, 0); + err = mmc_sdio_init_card(host, rocr, NULL); if (err) goto err; |