]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
mmc: sdhci-sprd: Fix the incorrect soft reset operation when runtime resuming
authorBaolin Wang <baolin.wang@linaro.org>
Thu, 25 Jul 2019 03:14:22 +0000 (11:14 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Sep 2019 06:23:22 +0000 (08:23 +0200)
[ Upstream commit c6303c5d52d5ec3e5bce2e6a5480fa2a1baa45e6 ]

The SD host controller specification defines 3 types software reset:
software reset for data line, software reset for command line and software
reset for all. Software reset for all means this reset affects the entire
Host controller except for the card detection circuit.

In sdhci_runtime_resume_host() we always do a software "reset for all",
which causes the Spreadtrum variant controller to work abnormally after
resuming. To fix the problem, let's do a software reset for the data and
the command part, rather than "for all".

However, as sdhci_runtime_resume() is a common sdhci function and we don't
want to change the behaviour for other variants, let's introduce a new
in-parameter for it. This enables the caller to decide if a "reset for all"
shall be done or not.

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci-pxav3.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/sdhci-sprd.c
drivers/mmc/host/sdhci-xenon.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h

index b3a130a9ee23312348ef8369c34182089e82d0a8..1604f512c7bd183b85d8b3ed0c91634ed715a4cf 100644 (file)
@@ -883,7 +883,7 @@ static int sdhci_acpi_runtime_resume(struct device *dev)
 
        sdhci_acpi_byt_setting(&c->pdev->dev);
 
-       return sdhci_runtime_resume_host(c->host);
+       return sdhci_runtime_resume_host(c->host, 0);
 }
 
 #endif
index c391510e9ef407d54c25f4326a574a2b4b059ce6..776a942162488e87e14f3d48fd2b285ab9ecd1cf 100644 (file)
@@ -1705,7 +1705,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
                esdhc_pltfm_set_clock(host, imx_data->actual_clock);
        }
 
-       err = sdhci_runtime_resume_host(host);
+       err = sdhci_runtime_resume_host(host, 0);
        if (err)
                goto disable_ipg_clk;
 
index d4993582f0f631c803cf159e57efc1f67ede1790..e7d1920729fbc98aa3fe527e3e2fce5a28379af5 100644 (file)
@@ -289,7 +289,7 @@ static int sdhci_at91_runtime_resume(struct device *dev)
        }
 
 out:
-       return sdhci_runtime_resume_host(host);
+       return sdhci_runtime_resume_host(host, 0);
 }
 #endif /* CONFIG_PM */
 
index 4154ee11b47dc59a6927ffc50e06c388f962c88c..267b90374fa483e9ce734f80b91e34a5f7698efc 100644 (file)
@@ -167,7 +167,7 @@ static int sdhci_pci_runtime_suspend_host(struct sdhci_pci_chip *chip)
 
 err_pci_runtime_suspend:
        while (--i >= 0)
-               sdhci_runtime_resume_host(chip->slots[i]->host);
+               sdhci_runtime_resume_host(chip->slots[i]->host, 0);
        return ret;
 }
 
@@ -181,7 +181,7 @@ static int sdhci_pci_runtime_resume_host(struct sdhci_pci_chip *chip)
                if (!slot)
                        continue;
 
-               ret = sdhci_runtime_resume_host(slot->host);
+               ret = sdhci_runtime_resume_host(slot->host, 0);
                if (ret)
                        return ret;
        }
index 3ddecf47929585d6ca236fe17047316b9f8a1af5..e55037ceda734ff0e581fc8e2eecb664d882363f 100644 (file)
@@ -554,7 +554,7 @@ static int sdhci_pxav3_runtime_resume(struct device *dev)
        if (!IS_ERR(pxa->clk_core))
                clk_prepare_enable(pxa->clk_core);
 
-       return sdhci_runtime_resume_host(host);
+       return sdhci_runtime_resume_host(host, 0);
 }
 #endif
 
index 8e4a8ba33f0503bc52903755d3bd422bec233224..f5753aef71511d8bb495610858469ab3f1df028f 100644 (file)
@@ -745,7 +745,7 @@ static int sdhci_s3c_runtime_resume(struct device *dev)
        clk_prepare_enable(busclk);
        if (ourhost->cur_clk >= 0)
                clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
-       ret = sdhci_runtime_resume_host(host);
+       ret = sdhci_runtime_resume_host(host, 0);
        return ret;
 }
 #endif
index fc892a8d882fd1c868e57e9425ae2e3154a78dbd..53f3af53b3fba4025e68c218a84a91710ef123fa 100644 (file)
@@ -497,7 +497,7 @@ static int sdhci_sprd_runtime_resume(struct device *dev)
                return ret;
        }
 
-       sdhci_runtime_resume_host(host);
+       sdhci_runtime_resume_host(host, 1);
 
        return 0;
 }
index 8a18f14cf842df20afd0609e973a7e5d5546349d..1dea1ba66f7b4e8a05e48a8a0f4fbac8875c2a14 100644 (file)
@@ -638,7 +638,7 @@ static int xenon_runtime_resume(struct device *dev)
                priv->restore_needed = false;
        }
 
-       ret = sdhci_runtime_resume_host(host);
+       ret = sdhci_runtime_resume_host(host, 0);
        if (ret)
                goto out;
        return 0;
index 59acf8e3331ee189fce0fbf2468478b48c41154c..a5dc5aae973e6e14f3915dae1c44d247a7ac7bfb 100644 (file)
@@ -3320,7 +3320,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
 }
 EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host);
 
-int sdhci_runtime_resume_host(struct sdhci_host *host)
+int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset)
 {
        struct mmc_host *mmc = host->mmc;
        unsigned long flags;
@@ -3331,7 +3331,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
                        host->ops->enable_dma(host);
        }
 
-       sdhci_init(host, 0);
+       sdhci_init(host, soft_reset);
 
        if (mmc->ios.power_mode != MMC_POWER_UNDEFINED &&
            mmc->ios.power_mode != MMC_POWER_OFF) {
index 199712e7adbb3dad5c1ab6e306448d6fd32648a2..d2c7c9c436c978ec41fb9cb73a42b3a5f2126347 100644 (file)
@@ -781,7 +781,7 @@ void sdhci_adma_write_desc(struct sdhci_host *host, void **desc,
 int sdhci_suspend_host(struct sdhci_host *host);
 int sdhci_resume_host(struct sdhci_host *host);
 int sdhci_runtime_suspend_host(struct sdhci_host *host);
-int sdhci_runtime_resume_host(struct sdhci_host *host);
+int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset);
 #endif
 
 void sdhci_cqe_enable(struct mmc_host *mmc);