mmc: sdhci: Let drivers decide whether to use mmc_retune_needed() with pm
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 20 Mar 2017 17:50:32 +0000 (19:50 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 24 Apr 2017 19:41:26 +0000 (21:41 +0200)
Devices might save and restore tuning values so that re-tuning might not be
needed after a pm transition.  Let drivers decide by pushing the
mmc_retune_needed() logic down to them.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Ludovic Desroches <ludovic.desroches@microchip.com>
15 files changed:
drivers/mmc/host/sdhci-acpi.c
drivers/mmc/host/sdhci-brcmstb.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-of-arasan.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-of-esdhc.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci-pci.h
drivers/mmc/host/sdhci-pltfm.c
drivers/mmc/host/sdhci-pxav3.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/sdhci-sirf.c
drivers/mmc/host/sdhci-spear.c
drivers/mmc/host/sdhci-st.c
drivers/mmc/host/sdhci.c

index 9dcb7048e3b15b6a1c0e1f321e7f267a9319fb20..665c5f3009b424cf21383dab7dadddeb80abfece 100644 (file)
@@ -524,8 +524,12 @@ static int sdhci_acpi_remove(struct platform_device *pdev)
 static int sdhci_acpi_suspend(struct device *dev)
 {
        struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+       struct sdhci_host *host = c->host;
 
-       return sdhci_suspend_host(c->host);
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
+       return sdhci_suspend_host(host);
 }
 
 static int sdhci_acpi_resume(struct device *dev)
@@ -544,8 +548,12 @@ static int sdhci_acpi_resume(struct device *dev)
 static int sdhci_acpi_runtime_suspend(struct device *dev)
 {
        struct sdhci_acpi_host *c = dev_get_drvdata(dev);
+       struct sdhci_host *host = c->host;
+
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
 
-       return sdhci_runtime_suspend_host(c->host);
+       return sdhci_runtime_suspend_host(host);
 }
 
 static int sdhci_acpi_runtime_resume(struct device *dev)
index 159f6f64c68e78fb11cd86c9472df97aae9e6ad8..242c5dc7a81eadf565ba659b1a118b80fd8fb7ca 100644 (file)
@@ -29,6 +29,9 @@ static int sdhci_brcmstb_suspend(struct device *dev)
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        int res;
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        res = sdhci_suspend_host(host);
        if (res)
                return res;
index 445fc47dc3e77e39b17e7531eb7dbed58ddd3279..abad67aeabdd93ce3c9578deb8fc275310b4a95b 100644 (file)
@@ -1323,6 +1323,9 @@ static int sdhci_esdhc_suspend(struct device *dev)
 {
        struct sdhci_host *host = dev_get_drvdata(dev);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        return sdhci_suspend_host(host);
 }
 
@@ -1347,6 +1350,9 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
 
        ret = sdhci_runtime_suspend_host(host);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        if (!sdhci_sdio_irq_enabled(host)) {
                clk_disable_unprepare(imx_data->clk_per);
                clk_disable_unprepare(imx_data->clk_ipg);
index 1cfd7f90033944c6a6441aaf7256b1ce44350354..28feb5367c1459392803eae932df154cabe86d22 100644 (file)
@@ -315,6 +315,9 @@ static int sdhci_arasan_suspend(struct device *dev)
        struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
        int ret;
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        ret = sdhci_suspend_host(host);
        if (ret)
                return ret;
index d5430ed02a67896616bd1371a22f51bb59be8ee2..3f08b7ebec438b5635b8fdb2626be8bd6435224d 100644 (file)
@@ -140,6 +140,9 @@ static int sdhci_at91_runtime_suspend(struct device *dev)
 
        ret = sdhci_runtime_suspend_host(host);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        clk_disable_unprepare(priv->gck);
        clk_disable_unprepare(priv->hclock);
        clk_disable_unprepare(priv->mainck);
index d3aa67142839b2e36e654febd911d8e9eee129b6..ff37e745938674f2c2d2b2ff44ae834aaa5667c2 100644 (file)
@@ -528,6 +528,9 @@ static int esdhc_of_suspend(struct device *dev)
 
        esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        return sdhci_suspend_host(host);
 }
 
index 86560d590786f3f62a65c8668f2e601fd27b75be..b7150e935fb642f4a83a69c556f3af53b5d81157 100644 (file)
@@ -1653,6 +1653,7 @@ static int sdhci_pci_suspend(struct device *dev)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct sdhci_pci_chip *chip;
        struct sdhci_pci_slot *slot;
+       struct sdhci_host *host;
        mmc_pm_flag_t slot_pm_flags;
        mmc_pm_flag_t pm_flags = 0;
        int i, ret;
@@ -1666,14 +1667,19 @@ static int sdhci_pci_suspend(struct device *dev)
                if (!slot)
                        continue;
 
-               ret = sdhci_suspend_host(slot->host);
+               host = slot->host;
+
+               if (chip->pm_retune && host->tuning_mode != SDHCI_TUNING_MODE_3)
+                       mmc_retune_needed(host->mmc);
+
+               ret = sdhci_suspend_host(host);
 
                if (ret)
                        goto err_pci_suspend;
 
-               slot_pm_flags = slot->host->mmc->pm_flags;
+               slot_pm_flags = host->mmc->pm_flags;
                if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
-                       sdhci_enable_irq_wakeups(slot->host);
+                       sdhci_enable_irq_wakeups(host);
 
                pm_flags |= slot_pm_flags;
        }
@@ -1737,6 +1743,7 @@ static int sdhci_pci_runtime_suspend(struct device *dev)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct sdhci_pci_chip *chip;
        struct sdhci_pci_slot *slot;
+       struct sdhci_host *host;
        int i, ret;
 
        chip = pci_get_drvdata(pdev);
@@ -1748,10 +1755,15 @@ static int sdhci_pci_runtime_suspend(struct device *dev)
                if (!slot)
                        continue;
 
-               ret = sdhci_runtime_suspend_host(slot->host);
+               host = slot->host;
 
+               ret = sdhci_runtime_suspend_host(host);
                if (ret)
                        goto err_pci_runtime_suspend;
+
+               if (chip->rpm_retune &&
+                   host->tuning_mode != SDHCI_TUNING_MODE_3)
+                       mmc_retune_needed(host->mmc);
        }
 
        if (chip->fixes && chip->fixes->suspend) {
@@ -2042,6 +2054,8 @@ static int sdhci_pci_probe(struct pci_dev *pdev,
                chip->allow_runtime_pm = chip->fixes->allow_runtime_pm;
        }
        chip->num_slots = slots;
+       chip->pm_retune = true;
+       chip->rpm_retune = true;
 
        pci_set_drvdata(pdev, chip);
 
index 36f743464fcceded6afa7fcb0aaf8e7f26c1440c..e6e916b3361e5b3522741af021703bf85d72f2ee 100644 (file)
@@ -97,6 +97,8 @@ struct sdhci_pci_chip {
        unsigned int            quirks;
        unsigned int            quirks2;
        bool                    allow_runtime_pm;
+       bool                    pm_retune;
+       bool                    rpm_retune;
        const struct sdhci_pci_fixes *fixes;
 
        int                     num_slots;      /* Slots on controller */
index ad49bfaf5bf8d0f81ab306df5155d49a91a008ca..e090d8c42ddb22af1b2226072bc9617635d70a5a 100644 (file)
@@ -213,6 +213,9 @@ static int sdhci_pltfm_suspend(struct device *dev)
 {
        struct sdhci_host *host = dev_get_drvdata(dev);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        return sdhci_suspend_host(host);
 }
 
index 132670a612a0b17325a61c97853612aa985144d9..22ed90433d291cf5e258ce8de4fee40e706fc211 100644 (file)
@@ -527,6 +527,8 @@ static int sdhci_pxav3_suspend(struct device *dev)
        struct sdhci_host *host = dev_get_drvdata(dev);
 
        pm_runtime_get_sync(dev);
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
        ret = sdhci_suspend_host(host);
        pm_runtime_mark_last_busy(dev);
        pm_runtime_put_autosuspend(dev);
@@ -560,6 +562,9 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
        if (ret)
                return ret;
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        clk_disable_unprepare(pxa->clk_io);
        if (!IS_ERR(pxa->clk_core))
                clk_disable_unprepare(pxa->clk_core);
index 3e5c83d435ae0078c1e6adca66feb5375169faf1..d02284da2ec612e6671630e2fdacedcefcd45d8a 100644 (file)
@@ -743,6 +743,9 @@ static int sdhci_s3c_suspend(struct device *dev)
 {
        struct sdhci_host *host = dev_get_drvdata(dev);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        return sdhci_suspend_host(host);
 }
 
@@ -764,6 +767,9 @@ static int sdhci_s3c_runtime_suspend(struct device *dev)
 
        ret = sdhci_runtime_suspend_host(host);
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        if (ourhost->cur_clk >= 0)
                clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
        clk_disable_unprepare(busclk);
index 5d068639dd3f94fc862e8fcefe1609791c18fbd5..c251c6c0a112dbeccb3a4854be72b60ffc03b76f 100644 (file)
@@ -237,6 +237,9 @@ static int sdhci_sirf_suspend(struct device *dev)
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        int ret;
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        ret = sdhci_suspend_host(host);
        if (ret)
                return ret;
index 255a896769b8691ee9178fb5502e3844ccd1555f..8c0f88428556cec966733a0db0fe2dccfba3d252 100644 (file)
@@ -165,6 +165,9 @@ static int sdhci_suspend(struct device *dev)
        struct spear_sdhci *sdhci = sdhci_priv(host);
        int ret;
 
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
+
        ret = sdhci_suspend_host(host);
        if (!ret)
                clk_disable(sdhci->clk);
index 7fff6490855cf9bc64ee223856ec7e3f762c60c6..68c36c9fa23184e8c0d7e01733199089449384ab 100644 (file)
@@ -463,8 +463,12 @@ static int sdhci_st_suspend(struct device *dev)
        struct sdhci_host *host = dev_get_drvdata(dev);
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
-       int ret = sdhci_suspend_host(host);
+       int ret;
+
+       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+               mmc_retune_needed(host->mmc);
 
+       ret = sdhci_suspend_host(host);
        if (ret)
                goto out;
 
index 777c82efce1d5286ecc98ac3c943199f59f878f1..105f4448145d7670e251a50ec680292b3b334ddc 100644 (file)
@@ -2857,8 +2857,6 @@ int sdhci_suspend_host(struct sdhci_host *host)
        sdhci_disable_card_detection(host);
 
        mmc_retune_timer_stop(host->mmc);
-       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
-               mmc_retune_needed(host->mmc);
 
        if (!device_may_wakeup(mmc_dev(host->mmc))) {
                host->ier = 0;
@@ -2919,8 +2917,6 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
        unsigned long flags;
 
        mmc_retune_timer_stop(host->mmc);
-       if (host->tuning_mode != SDHCI_TUNING_MODE_3)
-               mmc_retune_needed(host->mmc);
 
        spin_lock_irqsave(&host->lock, flags);
        host->ier &= SDHCI_INT_CARD_INT;