Commit 8140e736 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.3-rc4' of git://git.linaro.org/people/ulf.hansson/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC host:
   - omap_hsmmc: Fix boot regressions for omap4430
   - omap_hsmmc: Fix legacy boot regression for omap3
   - sdhci-pxav3: Fix some clock issues for Armada 38x
   - sdhci-pxav3: Fix error handling at probe
   - sdhci-of-at91: Fix clock stabilization problem"

* tag 'mmc-v4.3-rc4' of git://git.linaro.org/people/ulf.hansson/mmc:
  mmc: sdhci-of-at91: use SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST quirk
  mmc: sdhci: add quirk SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST
  mmc: sdhci-pxav3: fix error handling of armada_38x_quirks
  mmc: sdhci-pxav3: disable clock inversion for HS MMC cards
  mmc: sdhci-pxav3: remove broken clock base quirk for Armada 38x sdhci driver
  mmc: host: omap_hsmmc: Fix MMC for omap3 legacy booting
  Revert "mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status"
parents 04445556 88c6eb0e
...@@ -182,6 +182,7 @@ struct omap_hsmmc_host { ...@@ -182,6 +182,7 @@ struct omap_hsmmc_host {
struct clk *fclk; struct clk *fclk;
struct clk *dbclk; struct clk *dbclk;
struct regulator *pbias; struct regulator *pbias;
bool pbias_enabled;
void __iomem *base; void __iomem *base;
int vqmmc_enabled; int vqmmc_enabled;
resource_size_t mapbase; resource_size_t mapbase;
...@@ -328,20 +329,22 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, ...@@ -328,20 +329,22 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
return ret; return ret;
} }
if (!regulator_is_enabled(host->pbias)) { if (host->pbias_enabled == 0) {
ret = regulator_enable(host->pbias); ret = regulator_enable(host->pbias);
if (ret) { if (ret) {
dev_err(host->dev, "pbias reg enable fail\n"); dev_err(host->dev, "pbias reg enable fail\n");
return ret; return ret;
} }
host->pbias_enabled = 1;
} }
} else { } else {
if (regulator_is_enabled(host->pbias)) { if (host->pbias_enabled == 1) {
ret = regulator_disable(host->pbias); ret = regulator_disable(host->pbias);
if (ret) { if (ret) {
dev_err(host->dev, "pbias reg disable fail\n"); dev_err(host->dev, "pbias reg disable fail\n");
return ret; return ret;
} }
host->pbias_enabled = 0;
} }
} }
...@@ -475,7 +478,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) ...@@ -475,7 +478,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc"); mmc->supply.vmmc = devm_regulator_get_optional(host->dev, "vmmc");
if (IS_ERR(mmc->supply.vmmc)) { if (IS_ERR(mmc->supply.vmmc)) {
ret = PTR_ERR(mmc->supply.vmmc); ret = PTR_ERR(mmc->supply.vmmc);
if (ret != -ENODEV) if ((ret != -ENODEV) && host->dev->of_node)
return ret; return ret;
dev_dbg(host->dev, "unable to get vmmc regulator %ld\n", dev_dbg(host->dev, "unable to get vmmc regulator %ld\n",
PTR_ERR(mmc->supply.vmmc)); PTR_ERR(mmc->supply.vmmc));
...@@ -490,7 +493,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) ...@@ -490,7 +493,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux"); mmc->supply.vqmmc = devm_regulator_get_optional(host->dev, "vmmc_aux");
if (IS_ERR(mmc->supply.vqmmc)) { if (IS_ERR(mmc->supply.vqmmc)) {
ret = PTR_ERR(mmc->supply.vqmmc); ret = PTR_ERR(mmc->supply.vqmmc);
if (ret != -ENODEV) if ((ret != -ENODEV) && host->dev->of_node)
return ret; return ret;
dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n", dev_dbg(host->dev, "unable to get vmmc_aux regulator %ld\n",
PTR_ERR(mmc->supply.vqmmc)); PTR_ERR(mmc->supply.vqmmc));
...@@ -500,7 +503,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) ...@@ -500,7 +503,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
host->pbias = devm_regulator_get_optional(host->dev, "pbias"); host->pbias = devm_regulator_get_optional(host->dev, "pbias");
if (IS_ERR(host->pbias)) { if (IS_ERR(host->pbias)) {
ret = PTR_ERR(host->pbias); ret = PTR_ERR(host->pbias);
if (ret != -ENODEV) if ((ret != -ENODEV) && host->dev->of_node)
return ret; return ret;
dev_dbg(host->dev, "unable to get pbias regulator %ld\n", dev_dbg(host->dev, "unable to get pbias regulator %ld\n",
PTR_ERR(host->pbias)); PTR_ERR(host->pbias));
...@@ -2053,6 +2056,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) ...@@ -2053,6 +2056,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host->base = base + pdata->reg_offset; host->base = base + pdata->reg_offset;
host->power_mode = MMC_POWER_OFF; host->power_mode = MMC_POWER_OFF;
host->next_data.cookie = 1; host->next_data.cookie = 1;
host->pbias_enabled = 0;
host->vqmmc_enabled = 0; host->vqmmc_enabled = 0;
ret = omap_hsmmc_gpio_init(mmc, host, pdata); ret = omap_hsmmc_gpio_init(mmc, host, pdata);
......
...@@ -43,6 +43,7 @@ static const struct sdhci_ops sdhci_at91_sama5d2_ops = { ...@@ -43,6 +43,7 @@ static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
static const struct sdhci_pltfm_data soc_data_sama5d2 = { static const struct sdhci_pltfm_data soc_data_sama5d2 = {
.ops = &sdhci_at91_sama5d2_ops, .ops = &sdhci_at91_sama5d2_ops,
.quirks2 = SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST,
}; };
static const struct of_device_id sdhci_at91_dt_match[] = { static const struct of_device_id sdhci_at91_dt_match[] = {
......
...@@ -135,6 +135,7 @@ static int armada_38x_quirks(struct platform_device *pdev, ...@@ -135,6 +135,7 @@ static int armada_38x_quirks(struct platform_device *pdev,
struct sdhci_pxa *pxa = pltfm_host->priv; struct sdhci_pxa *pxa = pltfm_host->priv;
struct resource *res; struct resource *res;
host->quirks &= ~SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
host->quirks |= SDHCI_QUIRK_MISSING_CAPS; host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"conf-sdio3"); "conf-sdio3");
...@@ -290,6 +291,9 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) ...@@ -290,6 +291,9 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
uhs == MMC_TIMING_UHS_DDR50) { uhs == MMC_TIMING_UHS_DDR50) {
reg_val &= ~SDIO3_CONF_CLK_INV; reg_val &= ~SDIO3_CONF_CLK_INV;
reg_val |= SDIO3_CONF_SD_FB_CLK; reg_val |= SDIO3_CONF_SD_FB_CLK;
} else if (uhs == MMC_TIMING_MMC_HS) {
reg_val &= ~SDIO3_CONF_CLK_INV;
reg_val &= ~SDIO3_CONF_SD_FB_CLK;
} else { } else {
reg_val |= SDIO3_CONF_CLK_INV; reg_val |= SDIO3_CONF_CLK_INV;
reg_val &= ~SDIO3_CONF_SD_FB_CLK; reg_val &= ~SDIO3_CONF_SD_FB_CLK;
...@@ -398,7 +402,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) ...@@ -398,7 +402,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) {
ret = armada_38x_quirks(pdev, host); ret = armada_38x_quirks(pdev, host);
if (ret < 0) if (ret < 0)
goto err_clk_get; goto err_mbus_win;
ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info());
if (ret < 0) if (ret < 0)
goto err_mbus_win; goto err_mbus_win;
......
...@@ -1160,6 +1160,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) ...@@ -1160,6 +1160,8 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
host->mmc->actual_clock = 0; host->mmc->actual_clock = 0;
sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
if (host->quirks2 & SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST)
mdelay(1);
if (clock == 0) if (clock == 0)
return; return;
......
...@@ -412,6 +412,11 @@ struct sdhci_host { ...@@ -412,6 +412,11 @@ struct sdhci_host {
#define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14)
/* Broken Clock divider zero in controller */ /* Broken Clock divider zero in controller */
#define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15)
/*
* When internal clock is disabled, a delay is needed before modifying the
* SD clock frequency or enabling back the internal clock.
*/
#define SDHCI_QUIRK2_NEED_DELAY_AFTER_INT_CLK_RST (1<<16)
int irq; /* Device IRQ */ int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */ void __iomem *ioaddr; /* Mapped address */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment