diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-22 16:36:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-22 16:36:08 -0700 |
commit | a6be1fcbc57f95bb47ef3c8e4ee3d83731b8f21e (patch) | |
tree | 88d762edfd97e7cdb0b41b8fe20c1ddb204c28c9 /drivers/mmc/core/sd.c | |
parent | 5b160bd426946c85f32b15e5d34d62d2618a5a87 (diff) | |
parent | 30b87c60e9cbfcdfce22aa652fc1e5d061fcb733 (diff) | |
download | linux-stable-a6be1fcbc57f95bb47ef3c8e4ee3d83731b8f21e.tar.gz linux-stable-a6be1fcbc57f95bb47ef3c8e4ee3d83731b8f21e.tar.bz2 linux-stable-a6be1fcbc57f95bb47ef3c8e4ee3d83731b8f21e.zip |
Merge tag 'mmc-merge-for-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC updates from Chris Ball:
"MMC highlights for 3.6:
Core:
- Rename cd-gpio to slot-gpio and extend it to support more slot GPIO
functions, such as write-protect.
- Add a function to get regulators (Vdd and Vccq) for a host.
Drivers:
- sdhci-pxav2, sdhci-pxav3: Add device tree support.
- sdhi: Add device tree support.
- sh_mmcif: Add support for regulators, device tree, slot-gpio.
- tmio: Add regulator support, use slot-gpio."
* tag 'mmc-merge-for-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (62 commits)
mmc: sdhci-dove: Prepare for common clock framework
mmc: sdhci-dove: Add SDHCI_QUIRK_NO_HISPD_BIT
mmc: omap_hsmmc: ensure probe returns error upon resource failure
mmc: mxs-mmc: Add wp-inverted property
mmc: esdhc: Fix DMA_MASK to not break mx25 DMA access
mmc: core: reset signal voltage on power up
mmc: sd: Fix sd current limit setting
mmc: omap_hsmmc: add clk_prepare and clk_unprepare
mmc: sdhci: When a UHS switch fails, cycle power if regulator is used
mmc: atmel-mci: modify CLKDIV displaying in debugfs
mmc: atmel-mci: fix incorrect setting of host->data to NULL
mmc: sdhci: poll for card even when card is logically unremovable
mmc: sdhci: Introduce new flag SDHCI_USING_RETUNING_TIMER
mmc: sdio: Change pr_warning to pr_warn_ratelimited
mmc: core: Simplify and fix for SD switch processing
mmc: sdhci: restore host settings when card is removed
mmc: sdhci: fix incorrect command used in tuning
mmc: sdhci-pci: CaFe has broken card detection
mmc: sdhci: Report failure reasons for all cases in sdhci_add_host()
mmc: s3cmci: Convert s3cmci driver to gpiolib API
...
Diffstat (limited to 'drivers/mmc/core/sd.c')
-rw-r--r-- | drivers/mmc/core/sd.c | 171 |
1 files changed, 79 insertions, 92 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index b2b43f624b9e..74972c241dff 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -244,7 +244,7 @@ static int mmc_read_ssr(struct mmc_card *card) * bitfield positions accordingly. */ au = UNSTUFF_BITS(ssr, 428 - 384, 4); - if (au > 0 || au <= 9) { + if (au > 0 && au <= 9) { card->ssr.au = 1 << (au + 4); es = UNSTUFF_BITS(ssr, 408 - 384, 16); et = UNSTUFF_BITS(ssr, 402 - 384, 6); @@ -290,8 +290,12 @@ static int mmc_read_switch(struct mmc_card *card) return -ENOMEM; } - /* Find out the supported Bus Speed Modes. */ - err = mmc_sd_switch(card, 0, 0, 1, status); + /* + * Find out the card's support bits with a mode 0 operation. + * The argument does not matter, as the support bits do not + * change with the arguments. + */ + err = mmc_sd_switch(card, 0, 0, 0, status); if (err) { /* * If the host or the card can't do the switch, @@ -312,46 +316,8 @@ static int mmc_read_switch(struct mmc_card *card) if (card->scr.sda_spec3) { card->sw_caps.sd3_bus_mode = status[13]; - - /* Find out Driver Strengths supported by the card */ - err = mmc_sd_switch(card, 0, 2, 1, status); - if (err) { - /* - * If the host or the card can't do the switch, - * fail more gracefully. - */ - if (err != -EINVAL && err != -ENOSYS && err != -EFAULT) - goto out; - - pr_warning("%s: problem reading " - "Driver Strength.\n", - mmc_hostname(card->host)); - err = 0; - - goto out; - } - + /* Driver Strengths supported by the card */ card->sw_caps.sd3_drv_type = status[9]; - - /* Find out Current Limits supported by the card */ - err = mmc_sd_switch(card, 0, 3, 1, status); - if (err) { - /* - * If the host or the card can't do the switch, - * fail more gracefully. - */ - if (err != -EINVAL && err != -ENOSYS && err != -EFAULT) - goto out; - - pr_warning("%s: problem reading " - "Current Limit.\n", - mmc_hostname(card->host)); - err = 0; - - goto out; - } - - card->sw_caps.sd3_curr_limit = status[7]; } out: @@ -551,60 +517,80 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) return 0; } +/* Get host's max current setting at its current voltage */ +static u32 sd_get_host_max_current(struct mmc_host *host) +{ + u32 voltage, max_current; + + voltage = 1 << host->ios.vdd; + switch (voltage) { + case MMC_VDD_165_195: + max_current = host->max_current_180; + break; + case MMC_VDD_29_30: + case MMC_VDD_30_31: + max_current = host->max_current_300; + break; + case MMC_VDD_32_33: + case MMC_VDD_33_34: + max_current = host->max_current_330; + break; + default: + max_current = 0; + } + + return max_current; +} + static int sd_set_current_limit(struct mmc_card *card, u8 *status) { - int current_limit = 0; + int current_limit = SD_SET_CURRENT_NO_CHANGE; int err; + u32 max_current; /* * Current limit switch is only defined for SDR50, SDR104, and DDR50 - * bus speed modes. For other bus speed modes, we set the default - * current limit of 200mA. + * bus speed modes. For other bus speed modes, we do not change the + * current limit. */ - if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) || - (card->sd_bus_speed == UHS_SDR104_BUS_SPEED) || - (card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) { - if (card->host->caps & MMC_CAP_MAX_CURRENT_800) { - if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800) - current_limit = SD_SET_CURRENT_LIMIT_800; - else if (card->sw_caps.sd3_curr_limit & - SD_MAX_CURRENT_600) - current_limit = SD_SET_CURRENT_LIMIT_600; - else if (card->sw_caps.sd3_curr_limit & - SD_MAX_CURRENT_400) - current_limit = SD_SET_CURRENT_LIMIT_400; - else if (card->sw_caps.sd3_curr_limit & - SD_MAX_CURRENT_200) - current_limit = SD_SET_CURRENT_LIMIT_200; - } else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) { - if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600) - current_limit = SD_SET_CURRENT_LIMIT_600; - else if (card->sw_caps.sd3_curr_limit & - SD_MAX_CURRENT_400) - current_limit = SD_SET_CURRENT_LIMIT_400; - else if (card->sw_caps.sd3_curr_limit & - SD_MAX_CURRENT_200) - current_limit = SD_SET_CURRENT_LIMIT_200; - } else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) { - if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400) - current_limit = SD_SET_CURRENT_LIMIT_400; - else if (card->sw_caps.sd3_curr_limit & - SD_MAX_CURRENT_200) - current_limit = SD_SET_CURRENT_LIMIT_200; - } else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) { - if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200) - current_limit = SD_SET_CURRENT_LIMIT_200; - } - } else + if ((card->sd_bus_speed != UHS_SDR50_BUS_SPEED) && + (card->sd_bus_speed != UHS_SDR104_BUS_SPEED) && + (card->sd_bus_speed != UHS_DDR50_BUS_SPEED)) + return 0; + + /* + * Host has different current capabilities when operating at + * different voltages, so find out its max current first. + */ + max_current = sd_get_host_max_current(card->host); + + /* + * We only check host's capability here, if we set a limit that is + * higher than the card's maximum current, the card will be using its + * maximum current, e.g. if the card's maximum current is 300ma, and + * when we set current limit to 200ma, the card will draw 200ma, and + * when we set current limit to 400/600/800ma, the card will draw its + * maximum 300ma from the host. + */ + if (max_current >= 800) + current_limit = SD_SET_CURRENT_LIMIT_800; + else if (max_current >= 600) + current_limit = SD_SET_CURRENT_LIMIT_600; + else if (max_current >= 400) + current_limit = SD_SET_CURRENT_LIMIT_400; + else if (max_current >= 200) current_limit = SD_SET_CURRENT_LIMIT_200; - err = mmc_sd_switch(card, 1, 3, current_limit, status); - if (err) - return err; + if (current_limit != SD_SET_CURRENT_NO_CHANGE) { + err = mmc_sd_switch(card, 1, 3, current_limit, status); + if (err) + return err; - if (((status[15] >> 4) & 0x0F) != current_limit) - pr_warning("%s: Problem setting current limit!\n", - mmc_hostname(card->host)); + if (((status[15] >> 4) & 0x0F) != current_limit) + pr_warning("%s: Problem setting current limit!\n", + mmc_hostname(card->host)); + + } return 0; } @@ -726,6 +712,7 @@ struct device_type sd_type = { int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) { int err; + u32 max_current; /* * Since we're changing the OCR value, we seem to @@ -753,9 +740,12 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)) ocr |= SD_OCR_S18R; - /* If the host can supply more than 150mA, XPC should be set to 1. */ - if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 | - MMC_CAP_SET_XPC_180)) + /* + * If the host can supply more than 150mA at current voltage, + * XPC should be set to 1. + */ + max_current = sd_get_host_max_current(host); + if (max_current > 150) ocr |= SD_OCR_XPC; try_again: @@ -911,9 +901,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, BUG_ON(!host); WARN_ON(!host->claimed); - /* The initialization should be done at 3.3 V I/O voltage. */ - mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); - err = mmc_sd_get_cid(host, ocr, cid, &rocr); if (err) return err; |