diff options
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r-- | drivers/mmc/core/core.c | 67 |
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 | ||
1484 | void 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 | |||
1487 | int mmc_host_set_uhs_voltage(struct mmc_host *host) | 1495 | int 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 | ||
1677 | void mmc_power_off(struct mmc_host *host) | 1679 | void 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)); | ||
2097 | out: | 2106 | out: |
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 | } |
2452 | EXPORT_SYMBOL(mmc_hw_reset); | 2461 | EXPORT_SYMBOL(mmc_hw_reset); |
2453 | 2462 | ||
2463 | int 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 | } | ||
2485 | EXPORT_SYMBOL(mmc_sw_reset); | ||
2486 | |||
2454 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | 2487 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) |
2455 | { | 2488 | { |
2456 | host->f_init = freq; | 2489 | host->f_init = freq; |