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)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 6 Aug 2019 16:59:14 +0000 (18:59 +0200)
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>
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 b3a130a..1604f51 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 c391510..776a942 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 e377b9b..d4e7e8b 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 4041878..7d06e28 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 3ddecf4..e55037c 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 8e4a8ba..f5753ae 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 603a5d9..83a4767 100644 (file)
@@ -696,7 +696,7 @@ static int sdhci_sprd_runtime_resume(struct device *dev)
        if (ret)
                goto clk_disable;
 
-       sdhci_runtime_resume_host(host);
+       sdhci_runtime_resume_host(host, 1);
        return 0;
 
 clk_disable:
index 8a18f14..1dea1ba 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 59acf8e..a5dc5aa 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 89fd965..902f855 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);