aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:11:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:11:43 -0400
commitf60342fac9fae20ada2cd5faadbc2a1337cae03f (patch)
treefe64b1cb3ea699d819e5e808264903aee2d8dc9a /drivers/mmc/core/core.c
parent5231804cf9e584f3e7e763a0d6d2fffe011c1bce (diff)
parentef5332c10d4f332a2ac79e9ad5452f4e89d1815a (diff)
Merge tag 'mmc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Decrease polling rate for erase/trim/discard - Allow non-sleeping GPIOs for card detect - Improve mmc block removal path - Enable support for mmc_sw_reset() for SDIO cards - Add mmc_sw_reset() to allow users to do a soft reset of the card - Allow power delay to be tunable via DT - Allow card detect debounce delay to be tunable via DT - Enable new quirk to limit clock rate for Marvell 8887 chip - Don't show eMMC RPMB and BOOT areas in /proc/partitions - Add capability to avoid 3.3V signaling for fragile HWs MMC host: - Improve/fixup support for handle highmem pages - Remove depends on HAS_DMA in case of platform dependency - mvsdio: Enable support for erase/trim/discard - rtsx_usb: Enable support for erase/trim/discard - renesas_sdhi: Fix WP logic regressions - renesas_sdhi: Add r8a77965 support - renesas_sdhi: Add R8A77980 to whitelist - meson: Add optional support for device reset - meson: Add support for the Meson-AXG platform - dw_mmc: Add new driver for BlueField DW variant - mediatek: Add support for 64G DRAM DMA - sunxi: Deploy runtime PM support - jz4740: Add support for JZ4780 - jz4740: Enable support for DT based platforms - sdhci: Various improvement to timeout handling - sdhci: Disable support for HS200/HS400/UHS when no 1.8V support - sdhci-omap: Add support for controller in k2g SoC - sdhci-omap: Add workarounds for a couple of Erratas - sdhci-omap: Enable support for generic sdhci DT properties - sdhci-cadence: Re-send tune request to deal with errata - sdhci-pci: Fix 3.3V voltage switch for some BYT-based Intel controllers - sdhci-pci: Avoid 3.3V signaling on some NI 904x - sdhci-esdhc-imx: Use watermark levels for PIO access - sdhci-msm: Improve card detection handling - sdhci-msm: Add support voltage pad switching" * tag 'mmc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (104 commits) mmc: renesas_sdhi: really fix WP logic regressions mmc: mvsdio: Enable MMC_CAP_ERASE mmc: mvsdio: Respect card busy time out from mmc core mmc: sdhci-msm: Remove NO_CARD_NO_RESET quirk mmc: sunxi: Use ifdef rather than __maybe_unused mmc: mxmmc: Use ifdef rather than __maybe_unused mmc: mxmmc: include linux/highmem.h mmc: sunxi: mark PM functions as __maybe_unused mmc: Throttle calls to MMC_SEND_STATUS during mmc_do_erase() mmc: au1xmmc: handle highmem pages mmc: Allow non-sleeping GPIO cd mmc: sdhci-*: Don't emit error msg if sdhci_add_host() fails mmc: sd: Define name for default speed dtr mmc: core: Move calls to ->prepare_hs400_tuning() closer to mmc code mmc: sdhci-xenon: use match_string() helper mmc: wbsd: handle highmem pages mmc: ushc: handle highmem pages mmc: mxcmmc: handle highmem pages mmc: atmel-mci: use sg_copy_{from,to}_buffer mmc: android-goldfish: use sg_copy_{from,to}_buffer ...
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 121ce50b6d5e..281826d1fcca 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -50,9 +50,6 @@
50#include "sd_ops.h" 50#include "sd_ops.h"
51#include "sdio_ops.h" 51#include "sdio_ops.h"
52 52
53/* If the device is not responding */
54#define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
55
56/* The max erase timeout, used when host->max_busy_timeout isn't specified */ 53/* The max erase timeout, used when host->max_busy_timeout isn't specified */
57#define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ 54#define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */
58 55
@@ -1484,6 +1481,17 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
1484 1481
1485} 1482}
1486 1483
1484void mmc_set_initial_signal_voltage(struct mmc_host *host)
1485{
1486 /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */
1487 if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330))
1488 dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n");
1489 else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180))
1490 dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n");
1491 else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120))
1492 dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n");
1493}
1494
1487int mmc_host_set_uhs_voltage(struct mmc_host *host) 1495int mmc_host_set_uhs_voltage(struct mmc_host *host)
1488{ 1496{
1489 u32 clock; 1497 u32 clock;
@@ -1646,19 +1654,13 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
1646 /* Set initial state and call mmc_set_ios */ 1654 /* Set initial state and call mmc_set_ios */
1647 mmc_set_initial_state(host); 1655 mmc_set_initial_state(host);
1648 1656
1649 /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ 1657 mmc_set_initial_signal_voltage(host);
1650 if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330))
1651 dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n");
1652 else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180))
1653 dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n");
1654 else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120))
1655 dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n");
1656 1658
1657 /* 1659 /*
1658 * This delay should be sufficient to allow the power supply 1660 * This delay should be sufficient to allow the power supply
1659 * to reach the minimum voltage. 1661 * to reach the minimum voltage.
1660 */ 1662 */
1661 mmc_delay(10); 1663 mmc_delay(host->ios.power_delay_ms);
1662 1664
1663 mmc_pwrseq_post_power_on(host); 1665 mmc_pwrseq_post_power_on(host);
1664 1666
@@ -1671,7 +1673,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr)
1671 * This delay must be at least 74 clock sizes, or 1 ms, or the 1673 * This delay must be at least 74 clock sizes, or 1 ms, or the
1672 * time required to reach a stable voltage. 1674 * time required to reach a stable voltage.
1673 */ 1675 */
1674 mmc_delay(10); 1676 mmc_delay(host->ios.power_delay_ms);
1675} 1677}
1676 1678
1677void mmc_power_off(struct mmc_host *host) 1679void mmc_power_off(struct mmc_host *host)
@@ -1967,6 +1969,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
1967 unsigned int qty = 0, busy_timeout = 0; 1969 unsigned int qty = 0, busy_timeout = 0;
1968 bool use_r1b_resp = false; 1970 bool use_r1b_resp = false;
1969 unsigned long timeout; 1971 unsigned long timeout;
1972 int loop_udelay=64, udelay_max=32768;
1970 int err; 1973 int err;
1971 1974
1972 mmc_retune_hold(card->host); 1975 mmc_retune_hold(card->host);
@@ -2091,9 +2094,15 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
2091 err = -EIO; 2094 err = -EIO;
2092 goto out; 2095 goto out;
2093 } 2096 }
2097 if ((cmd.resp[0] & R1_READY_FOR_DATA) &&
2098 R1_CURRENT_STATE(cmd.resp[0]) != R1_STATE_PRG)
2099 break;
2100
2101 usleep_range(loop_udelay, loop_udelay*2);
2102 if (loop_udelay < udelay_max)
2103 loop_udelay *= 2;
2104 } while (1);
2094 2105
2095 } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
2096 (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
2097out: 2106out:
2098 mmc_retune_release(card->host); 2107 mmc_retune_release(card->host);
2099 return err; 2108 return err;
@@ -2435,22 +2444,46 @@ int mmc_hw_reset(struct mmc_host *host)
2435 return -EINVAL; 2444 return -EINVAL;
2436 2445
2437 mmc_bus_get(host); 2446 mmc_bus_get(host);
2438 if (!host->bus_ops || host->bus_dead || !host->bus_ops->reset) { 2447 if (!host->bus_ops || host->bus_dead || !host->bus_ops->hw_reset) {
2439 mmc_bus_put(host); 2448 mmc_bus_put(host);
2440 return -EOPNOTSUPP; 2449 return -EOPNOTSUPP;
2441 } 2450 }
2442 2451
2443 ret = host->bus_ops->reset(host); 2452 ret = host->bus_ops->hw_reset(host);
2444 mmc_bus_put(host); 2453 mmc_bus_put(host);
2445 2454
2446 if (ret) 2455 if (ret)
2447 pr_warn("%s: tried to reset card, got error %d\n", 2456 pr_warn("%s: tried to HW reset card, got error %d\n",
2448 mmc_hostname(host), ret); 2457 mmc_hostname(host), ret);
2449 2458
2450 return ret; 2459 return ret;
2451} 2460}
2452EXPORT_SYMBOL(mmc_hw_reset); 2461EXPORT_SYMBOL(mmc_hw_reset);
2453 2462
2463int mmc_sw_reset(struct mmc_host *host)
2464{
2465 int ret;
2466
2467 if (!host->card)
2468 return -EINVAL;
2469
2470 mmc_bus_get(host);
2471 if (!host->bus_ops || host->bus_dead || !host->bus_ops->sw_reset) {
2472 mmc_bus_put(host);
2473 return -EOPNOTSUPP;
2474 }
2475
2476 ret = host->bus_ops->sw_reset(host);
2477 mmc_bus_put(host);
2478
2479 if (ret)
2480 pr_warn("%s: tried to SW reset card, got error %d\n",
2481 mmc_hostname(host), ret);
2482
2483 return ret;
2484}
2485EXPORT_SYMBOL(mmc_sw_reset);
2486
2454static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) 2487static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
2455{ 2488{
2456 host->f_init = freq; 2489 host->f_init = freq;