summaryrefslogtreecommitdiff
path: root/drivers/mmc/core/sd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 09:31:09 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 09:31:09 -0800
commited5dc2372dba46e0ecd08791b1a0399d313e5cff (patch)
tree571319985b59a2963fb7580c24ee2aa1696359e2 /drivers/mmc/core/sd.c
parent0512c04a2b5d29a33d96d315e1d14c55f5148aa7 (diff)
parent0e786102949d7461859c6ce9f39c2c8d28e42db3 (diff)
Merge tag 'mmc-updates-for-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC update from Chris Ball: "MMC highlights for 3.9: Core: - Support for packed commands in eMMC 4.5. (This requires a host capability to be turned on. It increases write throughput by 20%+, but may also increase average write latency; more testing needed.) - Add DT bindings for capability flags. - Add mmc_of_parse() for shared DT parsing between drivers. Drivers: - android-goldfish: New MMC driver for the Android Goldfish emulator. - mvsdio: Add DT bindings, pinctrl, use slot-gpio for card detection. - omap_hsmmc: Fix boot hangs with RPMB partitions. - sdhci-bcm2835: New driver for controller used by Raspberry Pi. - sdhci-esdhc-imx: Add 8-bit data, auto CMD23 support, use slot-gpio. - sh_mmcif: Add support for eMMC DDR, bundled MMCIF IRQs. - tmio_mmc: Add DT bindings, support for vccq regulator" * tag 'mmc-updates-for-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (92 commits) mmc: tegra: assume CONFIG_OF, remove platform data mmc: add DT bindings for more MMC capability flags mmc: tmio: add support for the VccQ regulator mmc: tmio: remove unused and deprecated symbols mmc: sh_mobile_sdhi: use managed resource allocations mmc: sh_mobile_sdhi: remove unused .pdata field mmc: tmio-mmc: parse device-tree bindings mmc: tmio-mmc: define device-tree bindings mmc: sh_mmcif: use mmc_of_parse() to parse standard MMC DT bindings mmc: (cosmetic) remove "extern" from function declarations mmc: provide a standard MMC device-tree binding parser centrally mmc: detailed definition of CD and WP MMC line polarities in DT mmc: sdhi, tmio: only check flags in tmio-mmc driver proper mmc: sdhci: Fix parameter of sdhci_do_start_signal_voltage_switch() mmc: sdhci: check voltage range only on regulators aware of voltage value mmc: bcm2835: set SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK mmc: support packed write command for eMMC4.5 devices mmc: add packed command feature of eMMC4.5 mmc: rtsx: remove driving adjustment mmc: use regulator_can_change_voltage() instead of regulator_count_voltages ...
Diffstat (limited to 'drivers/mmc/core/sd.c')
-rw-r--r--drivers/mmc/core/sd.c44
1 files changed, 18 insertions, 26 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 74972c241dff..9e645e19cec6 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -444,8 +444,7 @@ static void sd_update_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)) {
card->sd_bus_speed = 0;
return;
}
@@ -713,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
@@ -734,10 +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 (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
- MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
+ if (retries && mmc_host_uhs(host))
ocr |= SD_OCR_S18R;
/*
@@ -748,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;
@@ -759,9 +765,12 @@ try_again:
*/
if (!mmc_host_is_spi(host) && rocr &&
((*rocr & 0x41000000) == 0x41000000)) {
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
- if (err) {
- ocr &= ~SD_OCR_S18R;
+ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
+ if (err == -EAGAIN) {
+ retries--;
+ goto try_again;
+ } else if (err) {
+ retries = 0;
goto try_again;
}
}
@@ -960,16 +969,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
/* Card is an ultra-high-speed card */
mmc_card_set_uhs(card);
-
- /*
- * Since initialization is now complete, enable preset
- * value registers for UHS-I cards.
- */
- if (host->ops->enable_preset_value) {
- mmc_host_clk_hold(card->host);
- host->ops->enable_preset_value(host, true);
- mmc_host_clk_release(card->host);
- }
} else {
/*
* Attempt to change to high-speed (if supported)
@@ -1148,13 +1147,6 @@ int mmc_attach_sd(struct mmc_host *host)
BUG_ON(!host);
WARN_ON(!host->claimed);
- /* Disable preset value enable if already set since last time */
- if (host->ops->enable_preset_value) {
- mmc_host_clk_hold(host);
- host->ops->enable_preset_value(host, false);
- mmc_host_clk_release(host);
- }
-
err = mmc_send_app_op_cond(host, 0, &ocr);
if (err)
return err;