diff options
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 14 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-of-at91.c | 1 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-pxav3.c | 6 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 5 |
5 files changed, 22 insertions, 6 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 781e4db31767..7fb0753abe30 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -182,6 +182,7 @@ struct omap_hsmmc_host { | |||
182 | struct clk *fclk; | 182 | struct clk *fclk; |
183 | struct clk *dbclk; | 183 | struct clk *dbclk; |
184 | struct regulator *pbias; | 184 | struct regulator *pbias; |
185 | bool pbias_enabled; | ||
185 | void __iomem *base; | 186 | void __iomem *base; |
186 | int vqmmc_enabled; | 187 | int vqmmc_enabled; |
187 | resource_size_t mapbase; | 188 | resource_size_t mapbase; |
@@ -328,20 +329,22 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, | |||
328 | return ret; | 329 | return ret; |
329 | } | 330 | } |
330 | 331 | ||
331 | if (!regulator_is_enabled(host->pbias)) { | 332 | if (host->pbias_enabled == 0) { |
332 | ret = regulator_enable(host->pbias); | 333 | ret = regulator_enable(host->pbias); |
333 | if (ret) { | 334 | if (ret) { |
334 | dev_err(host->dev, "pbias reg enable fail\n"); | 335 | dev_err(host->dev, "pbias reg enable fail\n"); |
335 | return ret; | 336 | return ret; |
336 | } | 337 | } |
338 | host->pbias_enabled = 1; | ||
337 | } | 339 | } |
338 | } else { | 340 | } else { |
339 | if (regulator_is_enabled(host->pbias)) { | 341 | if (host->pbias_enabled == 1) { |
340 | ret = regulator_disable(host->pbias); | 342 | ret = regulator_disable(host->pbias); |
341 | if (ret) { | 343 | if (ret) { |
342 | dev_err(host->dev, "pbias reg disable fail\n"); | 344 | dev_err(host->dev, "pbias reg disable fail\n"); |
343 | return ret; | 345 | return ret; |
344 | } | 346 | } |
347 | host->pbias_enabled = 0; | ||
345 | } | 348 | } |
346 | } | 349 | } |
347 | 350 | ||
@@ -475,7 +478,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
475 | mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc"); | 478 | mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc"); |
476 | if (IS_ERR(mmc->supply.vmmc)) { | 479 | if (IS_ERR(mmc->supply.vmmc)) { |
477 | ret = PTR_ERR(mmc->supply.vmmc); | 480 | ret = PTR_ERR(mmc->supply.vmmc); |
478 | if (ret != -ENODEV) | 481 | if ((ret != -ENODEV) && host->dev->of_node) |
479 | return ret; | 482 | return ret; |
480 | dev_dbg(host->dev, "unable to get vmmc regulator %ld\n", | 483 | dev_dbg(host->dev, "unable to get vmmc regulator %ld\n", |
481 | PTR_ERR(mmc->supply.vmmc)); | 484 | PTR_ERR(mmc->supply.vmmc)); |
@@ -490,7 +493,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
490 | mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux"); | 493 | mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux"); |
491 | if (IS_ERR(mmc->supply.vqmmc)) { | 494 | if (IS_ERR(mmc->supply.vqmmc)) { |
492 | ret = PTR_ERR(mmc->supply.vqmmc); | 495 | ret = PTR_ERR(mmc->supply.vqmmc); |
493 | if (ret != -ENODEV) | 496 | if ((ret != -ENODEV) && host->dev->of_node) |
494 | return ret; | 497 | return ret; |
495 | dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n", | 498 | dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n", |
496 | PTR_ERR(mmc->supply.vqmmc)); | 499 | PTR_ERR(mmc->supply.vqmmc)); |
@@ -500,7 +503,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
500 | host->pbias = devm_regulator_get_optional(host->dev, "pbias"); | 503 | host->pbias = devm_regulator_get_optional(host->dev, "pbias"); |
501 | if (IS_ERR(host->pbias)) { | 504 | if (IS_ERR(host->pbias)) { |
502 | ret = PTR_ERR(host->pbias); | 505 | ret = PTR_ERR(host->pbias); |
503 | if (ret != -ENODEV) | 506 | if ((ret != -ENODEV) && host->dev->of_node) |
504 | return ret; | 507 | return ret; |
505 | dev_dbg(host->dev, "unable to get pbias regulator %ld\n", | 508 | dev_dbg(host->dev, "unable to get pbias regulator %ld\n", |
506 | PTR_ERR(host->pbias)); | 509 | PTR_ERR(host->pbias)); |
@@ -2053,6 +2056,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2053 | host->base = base + pdata->reg_offset; | 2056 | host->base = base + pdata->reg_offset; |
2054 | host->power_mode = MMC_POWER_OFF; | 2057 | host->power_mode = MMC_POWER_OFF; |
2055 | host->next_data.cookie = 1; | 2058 | host->next_data.cookie = 1; |
2059 | host->pbias_enabled = 0; | ||
2056 | host->vqmmc_enabled = 0; | 2060 | host->vqmmc_enabled = 0; |
2057 | 2061 | ||
2058 | ret = omap_hsmmc_gpio_init(mmc, host, pdata); | 2062 | ret = omap_hsmmc_gpio_init(mmc, host, pdata); |
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c index d1556643a41d..a0f05de5409f 100644 --- a/drivers/mmc/host/sdhci-of-at91.c +++ b/drivers/mmc/host/sdhci-of-at91.c | |||
@@ -43,6 +43,7 @@ static const struct sdhci_ops sdhci_at91_sama5d2_ops = { | |||
43 | 43 | ||
44 | static const struct sdhci_pltfm_data soc_data_sama5d2 = { | 44 | static const struct sdhci_pltfm_data soc_data_sama5d2 = { |
45 | .ops = &sdhci_at91_sama5d2_ops, | 45 | .ops = &sdhci_at91_sama5d2_ops, |
46 | .quirks2 = SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST, | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | static const struct of_device_id sdhci_at91_dt_match[] = { | 49 | static const struct of_device_id sdhci_at91_dt_match[] = { |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 946d37f94a31..f5edf9d3a18a 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -135,6 +135,7 @@ static int armada_38x_quirks(struct platform_device *pdev, | |||
135 | struct sdhci_pxa *pxa = pltfm_host->priv; | 135 | struct sdhci_pxa *pxa = pltfm_host->priv; |
136 | struct resource *res; | 136 | struct resource *res; |
137 | 137 | ||
138 | host->quirks &= ~SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; | ||
138 | host->quirks |= SDHCI_QUIRK_MISSING_CAPS; | 139 | host->quirks |= SDHCI_QUIRK_MISSING_CAPS; |
139 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 140 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
140 | "conf-sdio3"); | 141 | "conf-sdio3"); |
@@ -290,6 +291,9 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) | |||
290 | uhs == MMC_TIMING_UHS_DDR50) { | 291 | uhs == MMC_TIMING_UHS_DDR50) { |
291 | reg_val &= ~SDIO3_CONF_CLK_INV; | 292 | reg_val &= ~SDIO3_CONF_CLK_INV; |
292 | reg_val |= SDIO3_CONF_SD_FB_CLK; | 293 | reg_val |= SDIO3_CONF_SD_FB_CLK; |
294 | } else if (uhs == MMC_TIMING_MMC_HS) { | ||
295 | reg_val &= ~SDIO3_CONF_CLK_INV; | ||
296 | reg_val &= ~SDIO3_CONF_SD_FB_CLK; | ||
293 | } else { | 297 | } else { |
294 | reg_val |= SDIO3_CONF_CLK_INV; | 298 | reg_val |= SDIO3_CONF_CLK_INV; |
295 | reg_val &= ~SDIO3_CONF_SD_FB_CLK; | 299 | reg_val &= ~SDIO3_CONF_SD_FB_CLK; |
@@ -398,7 +402,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
398 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | 402 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { |
399 | ret = armada_38x_quirks(pdev, host); | 403 | ret = armada_38x_quirks(pdev, host); |
400 | if (ret < 0) | 404 | if (ret < 0) |
401 | goto err_clk_get; | 405 | goto err_mbus_win; |
402 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | 406 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); |
403 | if (ret < 0) | 407 | if (ret < 0) |
404 | goto err_mbus_win; | 408 | goto err_mbus_win; |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 64b7fdbd1a9c..fbc7efdddcb5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1160,6 +1160,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1160 | host->mmc->actual_clock = 0; | 1160 | host->mmc->actual_clock = 0; |
1161 | 1161 | ||
1162 | sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); | 1162 | sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); |
1163 | if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST) | ||
1164 | mdelay(1); | ||
1163 | 1165 | ||
1164 | if (clock == 0) | 1166 | if (clock == 0) |
1165 | return; | 1167 | return; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 7c02ff46c8ac..9d4aa31b683a 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -412,6 +412,11 @@ struct sdhci_host { | |||
412 | #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) | 412 | #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) |
413 | /* Broken Clock divider zero in controller */ | 413 | /* Broken Clock divider zero in controller */ |
414 | #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) | 414 | #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) |
415 | /* | ||
416 | * When internal clock is disabled, a delay is needed before modifying the | ||
417 | * SD clock frequency or enabling back the internal clock. | ||
418 | */ | ||
419 | #define SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST (1<<16) | ||
415 | 420 | ||
416 | int irq; /* Device IRQ */ | 421 | int irq; /* Device IRQ */ |
417 | void __iomem *ioaddr; /* Mapped address */ | 422 | void __iomem *ioaddr; /* Mapped address */ |