diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 13:56:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 13:56:48 -0500 |
commit | aa7ed01f93ff7e149cad46f13f66b269d59c9bc0 (patch) | |
tree | ab46a44f3c83c75e1c81f211acd0d68ffe60dd7c /drivers/mmc/core/mmc.c | |
parent | 7796c11c728ad40ba4151d559a949c002deffb9a (diff) | |
parent | 017210d1c0dc2e2d3b142985cb31d90b98dc0f0f (diff) |
Merge tag 'mmc-v3.20-1' of git://git.linaro.org/people/ulf.hansson/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Support for MMC power sequences.
- SDIO function devicetree subnode parsing.
- Refactor the hardware reset routines and enable it for SD cards.
- Various code quality improvements, especially for slot-gpio.
MMC host:
- dw_mmc: Various fixes and cleanups.
- dw_mmc: Convert to mmc_send_tuning().
- moxart: Fix probe logic.
- sdhci: Various fixes and cleanups
- sdhci: Asynchronous request handling support.
- sdhci-pxav3: Various fixes and cleanups.
- sdhci-tegra: Fixes for T114, T124 and T132.
- rtsx: Various fixes and cleanups.
- rtsx: Support for SDIO.
- sdhi/tmio: Refactor and cleanup of header files.
- omap_hsmmc: Use slot-gpio and common MMC DT parser.
- Make all hosts to deal with errors from mmc_of_parse().
- sunxi: Various fixes and cleanups.
- sdhci: Support for Fujitsu SDHCI controller f_sdh30"
* tag 'mmc-v3.20-1' of git://git.linaro.org/people/ulf.hansson/mmc: (117 commits)
mmc: sdhci-s3c: solve problem with sleeping in atomic context
mmc: pwrseq: add driver for emmc hardware reset
mmc: moxart: fix probe logic
mmc: core: Invoke mmc_pwrseq_post_power_on() prior MMC_POWER_ON state
mmc: pwrseq_simple: Add optional reference clock support
mmc: pwrseq: Document optional clock for the simple power sequence
mmc: pwrseq_simple: Extend to support more pins
mmc: pwrseq: Document that simple sequence support more than one GPIO
mmc: Add hardware dependencies for sdhci-pxav3 and sdhci-pxav2
mmc: sdhci-pxav3: Modify clock settings for the SDR50 and DDR50 modes
mmc: sdhci-pxav3: Extend binding with SDIO3 conf reg for the Armada 38x
mmc: sdhci-pxav3: Fix Armada 38x controller's caps according to erratum ERR-7878951
mmc: sdhci-pxav3: Fix SDR50 and DDR50 capabilities for the Armada 38x flavor
mmc: sdhci: switch voltage before sdhci_set_ios in runtime resume
mmc: tegra: Write xfer_mode, CMD regs in together
mmc: Resolve BKOPS compatability issue
mmc: sdhci-pxav3: fix setting of pdata->clk_delay_cycles
mmc: dw_mmc: rockchip: remove incorrect __exit_p()
mmc: dw_mmc: exynos: remove incorrect __exit_p()
mmc: Fix menuconfig alignment of MMC_SDHCI_* options
...
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r-- | drivers/mmc/core/mmc.c | 101 |
1 files changed, 53 insertions, 48 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 7466ce098e60..1d41e8541f38 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -483,11 +483,13 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
483 | /* check whether the eMMC card supports BKOPS */ | 483 | /* check whether the eMMC card supports BKOPS */ |
484 | if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { | 484 | if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { |
485 | card->ext_csd.bkops = 1; | 485 | card->ext_csd.bkops = 1; |
486 | card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; | 486 | card->ext_csd.man_bkops_en = |
487 | (ext_csd[EXT_CSD_BKOPS_EN] & | ||
488 | EXT_CSD_MANUAL_BKOPS_MASK); | ||
487 | card->ext_csd.raw_bkops_status = | 489 | card->ext_csd.raw_bkops_status = |
488 | ext_csd[EXT_CSD_BKOPS_STATUS]; | 490 | ext_csd[EXT_CSD_BKOPS_STATUS]; |
489 | if (!card->ext_csd.bkops_en) | 491 | if (!card->ext_csd.man_bkops_en) |
490 | pr_info("%s: BKOPS_EN bit is not set\n", | 492 | pr_info("%s: MAN_BKOPS_EN bit is not set\n", |
491 | mmc_hostname(card->host)); | 493 | mmc_hostname(card->host)); |
492 | } | 494 | } |
493 | 495 | ||
@@ -1155,38 +1157,6 @@ bus_speed: | |||
1155 | return err; | 1157 | return err; |
1156 | } | 1158 | } |
1157 | 1159 | ||
1158 | const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE] = { | ||
1159 | 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, | ||
1160 | 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, | ||
1161 | 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, | ||
1162 | 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, | ||
1163 | 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, | ||
1164 | 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, | ||
1165 | 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, | ||
1166 | 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, | ||
1167 | }; | ||
1168 | EXPORT_SYMBOL(tuning_blk_pattern_4bit); | ||
1169 | |||
1170 | const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE] = { | ||
1171 | 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, | ||
1172 | 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, | ||
1173 | 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, | ||
1174 | 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, | ||
1175 | 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, | ||
1176 | 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, | ||
1177 | 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, | ||
1178 | 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, | ||
1179 | 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, | ||
1180 | 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, | ||
1181 | 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, | ||
1182 | 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, | ||
1183 | 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, | ||
1184 | 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, | ||
1185 | 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, | ||
1186 | 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, | ||
1187 | }; | ||
1188 | EXPORT_SYMBOL(tuning_blk_pattern_8bit); | ||
1189 | |||
1190 | /* | 1160 | /* |
1191 | * Execute tuning sequence to seek the proper bus operating | 1161 | * Execute tuning sequence to seek the proper bus operating |
1192 | * conditions for HS200 and HS400, which sends CMD21 to the device. | 1162 | * conditions for HS200 and HS400, which sends CMD21 to the device. |
@@ -1194,7 +1164,6 @@ EXPORT_SYMBOL(tuning_blk_pattern_8bit); | |||
1194 | static int mmc_hs200_tuning(struct mmc_card *card) | 1164 | static int mmc_hs200_tuning(struct mmc_card *card) |
1195 | { | 1165 | { |
1196 | struct mmc_host *host = card->host; | 1166 | struct mmc_host *host = card->host; |
1197 | int err = 0; | ||
1198 | 1167 | ||
1199 | /* | 1168 | /* |
1200 | * Timing should be adjusted to the HS400 target | 1169 | * Timing should be adjusted to the HS400 target |
@@ -1205,18 +1174,7 @@ static int mmc_hs200_tuning(struct mmc_card *card) | |||
1205 | if (host->ops->prepare_hs400_tuning) | 1174 | if (host->ops->prepare_hs400_tuning) |
1206 | host->ops->prepare_hs400_tuning(host, &host->ios); | 1175 | host->ops->prepare_hs400_tuning(host, &host->ios); |
1207 | 1176 | ||
1208 | if (host->ops->execute_tuning) { | 1177 | return mmc_execute_tuning(card); |
1209 | mmc_host_clk_hold(host); | ||
1210 | err = host->ops->execute_tuning(host, | ||
1211 | MMC_SEND_TUNING_BLOCK_HS200); | ||
1212 | mmc_host_clk_release(host); | ||
1213 | |||
1214 | if (err) | ||
1215 | pr_err("%s: tuning execution failed\n", | ||
1216 | mmc_hostname(host)); | ||
1217 | } | ||
1218 | |||
1219 | return err; | ||
1220 | } | 1178 | } |
1221 | 1179 | ||
1222 | /* | 1180 | /* |
@@ -1297,6 +1255,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1297 | } | 1255 | } |
1298 | 1256 | ||
1299 | /* | 1257 | /* |
1258 | * Call the optional HC's init_card function to handle quirks. | ||
1259 | */ | ||
1260 | if (host->ops->init_card) | ||
1261 | host->ops->init_card(host, card); | ||
1262 | |||
1263 | /* | ||
1300 | * For native busses: set card RCA and quit open drain mode. | 1264 | * For native busses: set card RCA and quit open drain mode. |
1301 | */ | 1265 | */ |
1302 | if (!mmc_host_is_spi(host)) { | 1266 | if (!mmc_host_is_spi(host)) { |
@@ -1821,6 +1785,46 @@ static int mmc_power_restore(struct mmc_host *host) | |||
1821 | return ret; | 1785 | return ret; |
1822 | } | 1786 | } |
1823 | 1787 | ||
1788 | int mmc_can_reset(struct mmc_card *card) | ||
1789 | { | ||
1790 | u8 rst_n_function; | ||
1791 | |||
1792 | rst_n_function = card->ext_csd.rst_n_function; | ||
1793 | if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) != EXT_CSD_RST_N_ENABLED) | ||
1794 | return 0; | ||
1795 | return 1; | ||
1796 | } | ||
1797 | EXPORT_SYMBOL(mmc_can_reset); | ||
1798 | |||
1799 | static int mmc_reset(struct mmc_host *host) | ||
1800 | { | ||
1801 | struct mmc_card *card = host->card; | ||
1802 | u32 status; | ||
1803 | |||
1804 | if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) | ||
1805 | return -EOPNOTSUPP; | ||
1806 | |||
1807 | if (!mmc_can_reset(card)) | ||
1808 | return -EOPNOTSUPP; | ||
1809 | |||
1810 | mmc_host_clk_hold(host); | ||
1811 | mmc_set_clock(host, host->f_init); | ||
1812 | |||
1813 | host->ops->hw_reset(host); | ||
1814 | |||
1815 | /* If the reset has happened, then a status command will fail */ | ||
1816 | if (!mmc_send_status(card, &status)) { | ||
1817 | mmc_host_clk_release(host); | ||
1818 | return -ENOSYS; | ||
1819 | } | ||
1820 | |||
1821 | /* Set initial state and call mmc_set_ios */ | ||
1822 | mmc_set_initial_state(host); | ||
1823 | mmc_host_clk_release(host); | ||
1824 | |||
1825 | return mmc_power_restore(host); | ||
1826 | } | ||
1827 | |||
1824 | static const struct mmc_bus_ops mmc_ops = { | 1828 | static const struct mmc_bus_ops mmc_ops = { |
1825 | .remove = mmc_remove, | 1829 | .remove = mmc_remove, |
1826 | .detect = mmc_detect, | 1830 | .detect = mmc_detect, |
@@ -1831,6 +1835,7 @@ static const struct mmc_bus_ops mmc_ops = { | |||
1831 | .power_restore = mmc_power_restore, | 1835 | .power_restore = mmc_power_restore, |
1832 | .alive = mmc_alive, | 1836 | .alive = mmc_alive, |
1833 | .shutdown = mmc_shutdown, | 1837 | .shutdown = mmc_shutdown, |
1838 | .reset = mmc_reset, | ||
1834 | }; | 1839 | }; |
1835 | 1840 | ||
1836 | /* | 1841 | /* |