diff options
| -rw-r--r-- | drivers/mmc/host/sdhci-acpi.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-pci.c | 25 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-pci.h | 3 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-pxav3.c | 15 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci.c | 74 | ||||
| -rw-r--r-- | include/linux/mmc/sdhci.h | 1 |
6 files changed, 86 insertions, 34 deletions
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index e3e56d35f0ee..970314e0aac8 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
| @@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { | |||
| 247 | { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, | 247 | { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, |
| 248 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, | 248 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, |
| 249 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, | 249 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, |
| 250 | { "INT344D" , NULL, &sdhci_acpi_slot_int_sdio }, | ||
| 250 | { "PNP0D40" }, | 251 | { "PNP0D40" }, |
| 251 | { }, | 252 | { }, |
| 252 | }; | 253 | }; |
| @@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { | |||
| 257 | { "INT33BB" }, | 258 | { "INT33BB" }, |
| 258 | { "INT33C6" }, | 259 | { "INT33C6" }, |
| 259 | { "INT3436" }, | 260 | { "INT3436" }, |
| 261 | { "INT344D" }, | ||
| 260 | { "PNP0D40" }, | 262 | { "PNP0D40" }, |
| 261 | { }, | 263 | { }, |
| 262 | }; | 264 | }; |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 03427755b902..4f38554ce679 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
| @@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = { | |||
| 993 | .subdevice = PCI_ANY_ID, | 993 | .subdevice = PCI_ANY_ID, |
| 994 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, | 994 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, |
| 995 | }, | 995 | }, |
| 996 | |||
| 997 | { | ||
| 998 | .vendor = PCI_VENDOR_ID_INTEL, | ||
| 999 | .device = PCI_DEVICE_ID_INTEL_SPT_EMMC, | ||
| 1000 | .subvendor = PCI_ANY_ID, | ||
| 1001 | .subdevice = PCI_ANY_ID, | ||
| 1002 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc, | ||
| 1003 | }, | ||
| 1004 | |||
| 1005 | { | ||
| 1006 | .vendor = PCI_VENDOR_ID_INTEL, | ||
| 1007 | .device = PCI_DEVICE_ID_INTEL_SPT_SDIO, | ||
| 1008 | .subvendor = PCI_ANY_ID, | ||
| 1009 | .subdevice = PCI_ANY_ID, | ||
| 1010 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio, | ||
| 1011 | }, | ||
| 1012 | |||
| 1013 | { | ||
| 1014 | .vendor = PCI_VENDOR_ID_INTEL, | ||
| 1015 | .device = PCI_DEVICE_ID_INTEL_SPT_SD, | ||
| 1016 | .subvendor = PCI_ANY_ID, | ||
| 1017 | .subdevice = PCI_ANY_ID, | ||
| 1018 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, | ||
| 1019 | }, | ||
| 1020 | |||
| 996 | { | 1021 | { |
| 997 | .vendor = PCI_VENDOR_ID_O2, | 1022 | .vendor = PCI_VENDOR_ID_O2, |
| 998 | .device = PCI_DEVICE_ID_O2_8120, | 1023 | .device = PCI_DEVICE_ID_O2_8120, |
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index d57c3d169914..1ec684d06d54 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
| @@ -21,6 +21,9 @@ | |||
| 21 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 | 21 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 |
| 22 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 | 22 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 |
| 23 | #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 | 23 | #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 |
| 24 | #define PCI_DEVICE_ID_INTEL_SPT_EMMC 0x9d2b | ||
| 25 | #define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c | ||
| 26 | #define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d | ||
| 24 | 27 | ||
| 25 | /* | 28 | /* |
| 26 | * PCI registers | 29 | * PCI registers |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 45238871192d..ca3424e7ef71 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
| @@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
| 300 | if (IS_ERR(host)) | 300 | if (IS_ERR(host)) |
| 301 | return PTR_ERR(host); | 301 | return PTR_ERR(host); |
| 302 | 302 | ||
| 303 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
| 304 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
| 305 | if (ret < 0) | ||
| 306 | goto err_mbus_win; | ||
| 307 | } | ||
| 308 | |||
| 309 | |||
| 310 | pltfm_host = sdhci_priv(host); | 303 | pltfm_host = sdhci_priv(host); |
| 311 | pltfm_host->priv = pxa; | 304 | pltfm_host->priv = pxa; |
| 312 | 305 | ||
| @@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
| 325 | if (!IS_ERR(pxa->clk_core)) | 318 | if (!IS_ERR(pxa->clk_core)) |
| 326 | clk_prepare_enable(pxa->clk_core); | 319 | clk_prepare_enable(pxa->clk_core); |
| 327 | 320 | ||
| 321 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
| 322 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
| 323 | if (ret < 0) | ||
| 324 | goto err_mbus_win; | ||
| 325 | } | ||
| 326 | |||
| 328 | /* enable 1/8V DDR capable */ | 327 | /* enable 1/8V DDR capable */ |
| 329 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | 328 | host->mmc->caps |= MMC_CAP_1_8V_DDR; |
| 330 | 329 | ||
| @@ -396,11 +395,11 @@ err_add_host: | |||
| 396 | pm_runtime_disable(&pdev->dev); | 395 | pm_runtime_disable(&pdev->dev); |
| 397 | err_of_parse: | 396 | err_of_parse: |
| 398 | err_cd_req: | 397 | err_cd_req: |
| 398 | err_mbus_win: | ||
| 399 | clk_disable_unprepare(pxa->clk_io); | 399 | clk_disable_unprepare(pxa->clk_io); |
| 400 | if (!IS_ERR(pxa->clk_core)) | 400 | if (!IS_ERR(pxa->clk_core)) |
| 401 | clk_disable_unprepare(pxa->clk_core); | 401 | clk_disable_unprepare(pxa->clk_core); |
| 402 | err_clk_get: | 402 | err_clk_get: |
| 403 | err_mbus_win: | ||
| 404 | sdhci_pltfm_free(pdev); | 403 | sdhci_pltfm_free(pdev); |
| 405 | return ret; | 404 | return ret; |
| 406 | } | 405 | } |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cbb245b58538..1453cd127921 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host) | |||
| 259 | 259 | ||
| 260 | del_timer_sync(&host->tuning_timer); | 260 | del_timer_sync(&host->tuning_timer); |
| 261 | host->flags &= ~SDHCI_NEEDS_RETUNING; | 261 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
| 262 | host->mmc->max_blk_count = | ||
| 263 | (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; | ||
| 264 | } | 262 | } |
| 265 | sdhci_enable_card_detection(host); | 263 | sdhci_enable_card_detection(host); |
| 266 | } | 264 | } |
| @@ -1353,6 +1351,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1353 | 1351 | ||
| 1354 | sdhci_runtime_pm_get(host); | 1352 | sdhci_runtime_pm_get(host); |
| 1355 | 1353 | ||
| 1354 | present = mmc_gpio_get_cd(host->mmc); | ||
| 1355 | |||
| 1356 | spin_lock_irqsave(&host->lock, flags); | 1356 | spin_lock_irqsave(&host->lock, flags); |
| 1357 | 1357 | ||
| 1358 | WARN_ON(host->mrq != NULL); | 1358 | WARN_ON(host->mrq != NULL); |
| @@ -1381,7 +1381,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 1381 | * zero: cd-gpio is used, and card is removed | 1381 | * zero: cd-gpio is used, and card is removed |
| 1382 | * one: cd-gpio is used, and card is present | 1382 | * one: cd-gpio is used, and card is present |
| 1383 | */ | 1383 | */ |
| 1384 | present = mmc_gpio_get_cd(host->mmc); | ||
| 1385 | if (present < 0) { | 1384 | if (present < 0) { |
| 1386 | /* If polling, assume that the card is always present. */ | 1385 | /* If polling, assume that the card is always present. */ |
| 1387 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) | 1386 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) |
| @@ -1880,6 +1879,18 @@ static int sdhci_card_busy(struct mmc_host *mmc) | |||
| 1880 | return !(present_state & SDHCI_DATA_LVL_MASK); | 1879 | return !(present_state & SDHCI_DATA_LVL_MASK); |
| 1881 | } | 1880 | } |
| 1882 | 1881 | ||
| 1882 | static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) | ||
| 1883 | { | ||
| 1884 | struct sdhci_host *host = mmc_priv(mmc); | ||
| 1885 | unsigned long flags; | ||
| 1886 | |||
| 1887 | spin_lock_irqsave(&host->lock, flags); | ||
| 1888 | host->flags |= SDHCI_HS400_TUNING; | ||
| 1889 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 1890 | |||
| 1891 | return 0; | ||
| 1892 | } | ||
| 1893 | |||
| 1883 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | 1894 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
| 1884 | { | 1895 | { |
| 1885 | struct sdhci_host *host = mmc_priv(mmc); | 1896 | struct sdhci_host *host = mmc_priv(mmc); |
| @@ -1887,10 +1898,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
| 1887 | int tuning_loop_counter = MAX_TUNING_LOOP; | 1898 | int tuning_loop_counter = MAX_TUNING_LOOP; |
| 1888 | int err = 0; | 1899 | int err = 0; |
| 1889 | unsigned long flags; | 1900 | unsigned long flags; |
| 1901 | unsigned int tuning_count = 0; | ||
| 1902 | bool hs400_tuning; | ||
| 1890 | 1903 | ||
| 1891 | sdhci_runtime_pm_get(host); | 1904 | sdhci_runtime_pm_get(host); |
| 1892 | spin_lock_irqsave(&host->lock, flags); | 1905 | spin_lock_irqsave(&host->lock, flags); |
| 1893 | 1906 | ||
| 1907 | hs400_tuning = host->flags & SDHCI_HS400_TUNING; | ||
| 1908 | host->flags &= ~SDHCI_HS400_TUNING; | ||
| 1909 | |||
| 1910 | if (host->tuning_mode == SDHCI_TUNING_MODE_1) | ||
| 1911 | tuning_count = host->tuning_count; | ||
| 1912 | |||
| 1894 | /* | 1913 | /* |
| 1895 | * The Host Controller needs tuning only in case of SDR104 mode | 1914 | * The Host Controller needs tuning only in case of SDR104 mode |
| 1896 | * and for SDR50 mode when Use Tuning for SDR50 is set in the | 1915 | * and for SDR50 mode when Use Tuning for SDR50 is set in the |
| @@ -1899,8 +1918,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
| 1899 | * tuning function has to be executed. | 1918 | * tuning function has to be executed. |
| 1900 | */ | 1919 | */ |
| 1901 | switch (host->timing) { | 1920 | switch (host->timing) { |
| 1921 | /* HS400 tuning is done in HS200 mode */ | ||
| 1902 | case MMC_TIMING_MMC_HS400: | 1922 | case MMC_TIMING_MMC_HS400: |
| 1923 | err = -EINVAL; | ||
| 1924 | goto out_unlock; | ||
| 1925 | |||
| 1903 | case MMC_TIMING_MMC_HS200: | 1926 | case MMC_TIMING_MMC_HS200: |
| 1927 | /* | ||
| 1928 | * Periodic re-tuning for HS400 is not expected to be needed, so | ||
| 1929 | * disable it here. | ||
| 1930 | */ | ||
| 1931 | if (hs400_tuning) | ||
| 1932 | tuning_count = 0; | ||
| 1933 | break; | ||
| 1934 | |||
| 1904 | case MMC_TIMING_UHS_SDR104: | 1935 | case MMC_TIMING_UHS_SDR104: |
| 1905 | break; | 1936 | break; |
| 1906 | 1937 | ||
| @@ -1911,9 +1942,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
| 1911 | /* FALLTHROUGH */ | 1942 | /* FALLTHROUGH */ |
| 1912 | 1943 | ||
| 1913 | default: | 1944 | default: |
| 1914 | spin_unlock_irqrestore(&host->lock, flags); | 1945 | goto out_unlock; |
| 1915 | sdhci_runtime_pm_put(host); | ||
| 1916 | return 0; | ||
| 1917 | } | 1946 | } |
| 1918 | 1947 | ||
| 1919 | if (host->ops->platform_execute_tuning) { | 1948 | if (host->ops->platform_execute_tuning) { |
| @@ -2037,24 +2066,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
| 2037 | } | 2066 | } |
| 2038 | 2067 | ||
| 2039 | out: | 2068 | out: |
| 2040 | /* | 2069 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
| 2041 | * If this is the very first time we are here, we start the retuning | 2070 | |
| 2042 | * timer. Since only during the first time, SDHCI_NEEDS_RETUNING | 2071 | if (tuning_count) { |
| 2043 | * flag won't be set, we check this condition before actually starting | ||
| 2044 | * the timer. | ||
| 2045 | */ | ||
| 2046 | if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && | ||
| 2047 | (host->tuning_mode == SDHCI_TUNING_MODE_1)) { | ||
| 2048 | host->flags |= SDHCI_USING_RETUNING_TIMER; | 2072 | host->flags |= SDHCI_USING_RETUNING_TIMER; |
| 2049 | mod_timer(&host->tuning_timer, jiffies + | 2073 | mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ); |
| 2050 | host->tuning_count * HZ); | ||
| 2051 | /* Tuning mode 1 limits the maximum data length to 4MB */ | ||
| 2052 | mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; | ||
| 2053 | } else if (host->flags & SDHCI_USING_RETUNING_TIMER) { | ||
| 2054 | host->flags &= ~SDHCI_NEEDS_RETUNING; | ||
| 2055 | /* Reload the new initial value for timer */ | ||
| 2056 | mod_timer(&host->tuning_timer, jiffies + | ||
| 2057 | host->tuning_count * HZ); | ||
| 2058 | } | 2074 | } |
| 2059 | 2075 | ||
| 2060 | /* | 2076 | /* |
| @@ -2070,6 +2086,7 @@ out: | |||
| 2070 | 2086 | ||
| 2071 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | 2087 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); |
| 2072 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | 2088 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
| 2089 | out_unlock: | ||
| 2073 | spin_unlock_irqrestore(&host->lock, flags); | 2090 | spin_unlock_irqrestore(&host->lock, flags); |
| 2074 | sdhci_runtime_pm_put(host); | 2091 | sdhci_runtime_pm_put(host); |
| 2075 | 2092 | ||
| @@ -2110,15 +2127,18 @@ static void sdhci_card_event(struct mmc_host *mmc) | |||
| 2110 | { | 2127 | { |
| 2111 | struct sdhci_host *host = mmc_priv(mmc); | 2128 | struct sdhci_host *host = mmc_priv(mmc); |
| 2112 | unsigned long flags; | 2129 | unsigned long flags; |
| 2130 | int present; | ||
| 2113 | 2131 | ||
| 2114 | /* First check if client has provided their own card event */ | 2132 | /* First check if client has provided their own card event */ |
| 2115 | if (host->ops->card_event) | 2133 | if (host->ops->card_event) |
| 2116 | host->ops->card_event(host); | 2134 | host->ops->card_event(host); |
| 2117 | 2135 | ||
| 2136 | present = sdhci_do_get_cd(host); | ||
| 2137 | |||
| 2118 | spin_lock_irqsave(&host->lock, flags); | 2138 | spin_lock_irqsave(&host->lock, flags); |
| 2119 | 2139 | ||
| 2120 | /* Check host->mrq first in case we are runtime suspended */ | 2140 | /* Check host->mrq first in case we are runtime suspended */ |
| 2121 | if (host->mrq && !sdhci_do_get_cd(host)) { | 2141 | if (host->mrq && !present) { |
| 2122 | pr_err("%s: Card removed during transfer!\n", | 2142 | pr_err("%s: Card removed during transfer!\n", |
| 2123 | mmc_hostname(host->mmc)); | 2143 | mmc_hostname(host->mmc)); |
| 2124 | pr_err("%s: Resetting controller.\n", | 2144 | pr_err("%s: Resetting controller.\n", |
| @@ -2142,6 +2162,7 @@ static const struct mmc_host_ops sdhci_ops = { | |||
| 2142 | .hw_reset = sdhci_hw_reset, | 2162 | .hw_reset = sdhci_hw_reset, |
| 2143 | .enable_sdio_irq = sdhci_enable_sdio_irq, | 2163 | .enable_sdio_irq = sdhci_enable_sdio_irq, |
| 2144 | .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, | 2164 | .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, |
| 2165 | .prepare_hs400_tuning = sdhci_prepare_hs400_tuning, | ||
| 2145 | .execute_tuning = sdhci_execute_tuning, | 2166 | .execute_tuning = sdhci_execute_tuning, |
| 2146 | .card_event = sdhci_card_event, | 2167 | .card_event = sdhci_card_event, |
| 2147 | .card_busy = sdhci_card_busy, | 2168 | .card_busy = sdhci_card_busy, |
| @@ -3260,8 +3281,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 3260 | mmc->max_segs = SDHCI_MAX_SEGS; | 3281 | mmc->max_segs = SDHCI_MAX_SEGS; |
| 3261 | 3282 | ||
| 3262 | /* | 3283 | /* |
| 3263 | * Maximum number of sectors in one transfer. Limited by DMA boundary | 3284 | * Maximum number of sectors in one transfer. Limited by SDMA boundary |
| 3264 | * size (512KiB). | 3285 | * size (512KiB). Note some tuning modes impose a 4MiB limit, but this |
| 3286 | * is less anyway. | ||
| 3265 | */ | 3287 | */ |
| 3266 | mmc->max_req_size = 524288; | 3288 | mmc->max_req_size = 524288; |
| 3267 | 3289 | ||
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 375af80bde7d..f767a0de611f 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h | |||
| @@ -137,6 +137,7 @@ struct sdhci_host { | |||
| 137 | #define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ | 137 | #define SDHCI_SDR104_NEEDS_TUNING (1<<10) /* SDR104/HS200 needs tuning */ |
| 138 | #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ | 138 | #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */ |
| 139 | #define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */ | 139 | #define SDHCI_USE_64_BIT_DMA (1<<12) /* Use 64-bit DMA */ |
| 140 | #define SDHCI_HS400_TUNING (1<<13) /* Tuning for HS400 */ | ||
| 140 | 141 | ||
| 141 | unsigned int version; /* SDHCI spec. version */ | 142 | unsigned int version; /* SDHCI spec. version */ |
| 142 | 143 | ||
