diff options
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index bd8a0982aec3..9ddef4763541 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -898,8 +898,13 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, | |||
898 | u16 mode; | 898 | u16 mode; |
899 | struct mmc_data *data = cmd->data; | 899 | struct mmc_data *data = cmd->data; |
900 | 900 | ||
901 | if (data == NULL) | 901 | if (data == NULL) { |
902 | /* clear Auto CMD settings for no data CMDs */ | ||
903 | mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); | ||
904 | sdhci_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | | ||
905 | SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE); | ||
902 | return; | 906 | return; |
907 | } | ||
903 | 908 | ||
904 | WARN_ON(!host->data); | 909 | WARN_ON(!host->data); |
905 | 910 | ||
@@ -1013,7 +1018,12 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
1013 | mdelay(1); | 1018 | mdelay(1); |
1014 | } | 1019 | } |
1015 | 1020 | ||
1016 | mod_timer(&host->timer, jiffies + 10 * HZ); | 1021 | timeout = jiffies; |
1022 | if (!cmd->data && cmd->cmd_timeout_ms > 9000) | ||
1023 | timeout += DIV_ROUND_UP(cmd->cmd_timeout_ms, 1000) * HZ + HZ; | ||
1024 | else | ||
1025 | timeout += 10 * HZ; | ||
1026 | mod_timer(&host->timer, timeout); | ||
1017 | 1027 | ||
1018 | host->cmd = cmd; | 1028 | host->cmd = cmd; |
1019 | 1029 | ||
@@ -1391,6 +1401,13 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1391 | mmc->card->type == MMC_TYPE_MMC ? | 1401 | mmc->card->type == MMC_TYPE_MMC ? |
1392 | MMC_SEND_TUNING_BLOCK_HS200 : | 1402 | MMC_SEND_TUNING_BLOCK_HS200 : |
1393 | MMC_SEND_TUNING_BLOCK; | 1403 | MMC_SEND_TUNING_BLOCK; |
1404 | |||
1405 | /* Here we need to set the host->mrq to NULL, | ||
1406 | * in case the pending finish_tasklet | ||
1407 | * finishes it incorrectly. | ||
1408 | */ | ||
1409 | host->mrq = NULL; | ||
1410 | |||
1394 | spin_unlock_irqrestore(&host->lock, flags); | 1411 | spin_unlock_irqrestore(&host->lock, flags); |
1395 | sdhci_execute_tuning(mmc, tuning_opcode); | 1412 | sdhci_execute_tuning(mmc, tuning_opcode); |
1396 | spin_lock_irqsave(&host->lock, flags); | 1413 | spin_lock_irqsave(&host->lock, flags); |
@@ -1845,12 +1862,12 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1845 | unsigned long timeout; | 1862 | unsigned long timeout; |
1846 | int err = 0; | 1863 | int err = 0; |
1847 | bool requires_tuning_nonuhs = false; | 1864 | bool requires_tuning_nonuhs = false; |
1865 | unsigned long flags; | ||
1848 | 1866 | ||
1849 | host = mmc_priv(mmc); | 1867 | host = mmc_priv(mmc); |
1850 | 1868 | ||
1851 | sdhci_runtime_pm_get(host); | 1869 | sdhci_runtime_pm_get(host); |
1852 | disable_irq(host->irq); | 1870 | spin_lock_irqsave(&host->lock, flags); |
1853 | spin_lock(&host->lock); | ||
1854 | 1871 | ||
1855 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1872 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1856 | 1873 | ||
@@ -1870,15 +1887,13 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1870 | requires_tuning_nonuhs) | 1887 | requires_tuning_nonuhs) |
1871 | ctrl |= SDHCI_CTRL_EXEC_TUNING; | 1888 | ctrl |= SDHCI_CTRL_EXEC_TUNING; |
1872 | else { | 1889 | else { |
1873 | spin_unlock(&host->lock); | 1890 | spin_unlock_irqrestore(&host->lock, flags); |
1874 | enable_irq(host->irq); | ||
1875 | sdhci_runtime_pm_put(host); | 1891 | sdhci_runtime_pm_put(host); |
1876 | return 0; | 1892 | return 0; |
1877 | } | 1893 | } |
1878 | 1894 | ||
1879 | if (host->ops->platform_execute_tuning) { | 1895 | if (host->ops->platform_execute_tuning) { |
1880 | spin_unlock(&host->lock); | 1896 | spin_unlock_irqrestore(&host->lock, flags); |
1881 | enable_irq(host->irq); | ||
1882 | err = host->ops->platform_execute_tuning(host, opcode); | 1897 | err = host->ops->platform_execute_tuning(host, opcode); |
1883 | sdhci_runtime_pm_put(host); | 1898 | sdhci_runtime_pm_put(host); |
1884 | return err; | 1899 | return err; |
@@ -1951,15 +1966,12 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1951 | host->cmd = NULL; | 1966 | host->cmd = NULL; |
1952 | host->mrq = NULL; | 1967 | host->mrq = NULL; |
1953 | 1968 | ||
1954 | spin_unlock(&host->lock); | 1969 | spin_unlock_irqrestore(&host->lock, flags); |
1955 | enable_irq(host->irq); | ||
1956 | |||
1957 | /* Wait for Buffer Read Ready interrupt */ | 1970 | /* Wait for Buffer Read Ready interrupt */ |
1958 | wait_event_interruptible_timeout(host->buf_ready_int, | 1971 | wait_event_interruptible_timeout(host->buf_ready_int, |
1959 | (host->tuning_done == 1), | 1972 | (host->tuning_done == 1), |
1960 | msecs_to_jiffies(50)); | 1973 | msecs_to_jiffies(50)); |
1961 | disable_irq(host->irq); | 1974 | spin_lock_irqsave(&host->lock, flags); |
1962 | spin_lock(&host->lock); | ||
1963 | 1975 | ||
1964 | if (!host->tuning_done) { | 1976 | if (!host->tuning_done) { |
1965 | pr_info(DRIVER_NAME ": Timeout waiting for " | 1977 | pr_info(DRIVER_NAME ": Timeout waiting for " |
@@ -2034,8 +2046,7 @@ out: | |||
2034 | err = 0; | 2046 | err = 0; |
2035 | 2047 | ||
2036 | sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier); | 2048 | sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier); |
2037 | spin_unlock(&host->lock); | 2049 | spin_unlock_irqrestore(&host->lock, flags); |
2038 | enable_irq(host->irq); | ||
2039 | sdhci_runtime_pm_put(host); | 2050 | sdhci_runtime_pm_put(host); |
2040 | 2051 | ||
2041 | return err; | 2052 | return err; |
@@ -3004,7 +3015,8 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3004 | /* SD3.0: SDR104 is supported so (for eMMC) the caps2 | 3015 | /* SD3.0: SDR104 is supported so (for eMMC) the caps2 |
3005 | * field can be promoted to support HS200. | 3016 | * field can be promoted to support HS200. |
3006 | */ | 3017 | */ |
3007 | mmc->caps2 |= MMC_CAP2_HS200; | 3018 | if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200)) |
3019 | mmc->caps2 |= MMC_CAP2_HS200; | ||
3008 | } else if (caps[1] & SDHCI_SUPPORT_SDR50) | 3020 | } else if (caps[1] & SDHCI_SUPPORT_SDR50) |
3009 | mmc->caps |= MMC_CAP_UHS_SDR50; | 3021 | mmc->caps |= MMC_CAP_UHS_SDR50; |
3010 | 3022 | ||