diff options
author | Johan Rudholm <johan.rudholm@stericsson.com> | 2013-01-28 14:08:27 (GMT) |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-02-24 19:37:07 (GMT) |
commit | 567c89032cfdda8047562abe450947ac01f2d3c7 (patch) | |
tree | 09bdcb03c610055c9c1b69220948619d62934142 /drivers | |
parent | d887874e0ead6a0b86b6046b872730c81c121352 (diff) | |
download | linux-567c89032cfdda8047562abe450947ac01f2d3c7.tar.xz |
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 <johan.rudholm@stericsson.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Wei WANG <wei_wang@realsil.com.cn>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/core.c | 35 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 4 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 3 |
5 files changed, 31 insertions, 21 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 789056f..bb794c7 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 9007de7..b9f18a2 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 0d7a979..8a3ad60 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 9373639..9a59fcd 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 3a64933..1a726ae 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; |