mmc: sdhci: Let drivers decide whether to use mmc_retune_needed() with pm

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>
This commit is contained in:
Adrian Hunter 2017-03-20 19:50:32 +02:00 committed by Ulf Hansson
parent 5a436cc0af
commit d38dcad4e7
15 changed files with 73 additions and 11 deletions

View File

@ -524,8 +524,12 @@ static int sdhci_acpi_remove(struct platform_device *pdev)
static int sdhci_acpi_suspend(struct device *dev) static int sdhci_acpi_suspend(struct device *dev)
{ {
struct sdhci_acpi_host *c = dev_get_drvdata(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) 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) static int sdhci_acpi_runtime_suspend(struct device *dev)
{ {
struct sdhci_acpi_host *c = dev_get_drvdata(dev); struct sdhci_acpi_host *c = dev_get_drvdata(dev);
struct sdhci_host *host = c->host;
return sdhci_runtime_suspend_host(c->host); if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
return sdhci_runtime_suspend_host(host);
} }
static int sdhci_acpi_runtime_resume(struct device *dev) static int sdhci_acpi_runtime_resume(struct device *dev)

View File

@ -29,6 +29,9 @@ static int sdhci_brcmstb_suspend(struct device *dev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
int res; int res;
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
res = sdhci_suspend_host(host); res = sdhci_suspend_host(host);
if (res) if (res)
return res; return res;

View File

@ -1323,6 +1323,9 @@ static int sdhci_esdhc_suspend(struct device *dev)
{ {
struct sdhci_host *host = dev_get_drvdata(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); return sdhci_suspend_host(host);
} }
@ -1347,6 +1350,9 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
ret = sdhci_runtime_suspend_host(host); 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)) { if (!sdhci_sdio_irq_enabled(host)) {
clk_disable_unprepare(imx_data->clk_per); clk_disable_unprepare(imx_data->clk_per);
clk_disable_unprepare(imx_data->clk_ipg); clk_disable_unprepare(imx_data->clk_ipg);

View File

@ -315,6 +315,9 @@ static int sdhci_arasan_suspend(struct device *dev)
struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
int ret; int ret;
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
ret = sdhci_suspend_host(host); ret = sdhci_suspend_host(host);
if (ret) if (ret)
return ret; return ret;

View File

@ -140,6 +140,9 @@ static int sdhci_at91_runtime_suspend(struct device *dev)
ret = sdhci_runtime_suspend_host(host); 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->gck);
clk_disable_unprepare(priv->hclock); clk_disable_unprepare(priv->hclock);
clk_disable_unprepare(priv->mainck); clk_disable_unprepare(priv->mainck);

View File

@ -528,6 +528,9 @@ static int esdhc_of_suspend(struct device *dev)
esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL); 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); return sdhci_suspend_host(host);
} }

View File

@ -1653,6 +1653,7 @@ static int sdhci_pci_suspend(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct sdhci_pci_chip *chip; struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot; struct sdhci_pci_slot *slot;
struct sdhci_host *host;
mmc_pm_flag_t slot_pm_flags; mmc_pm_flag_t slot_pm_flags;
mmc_pm_flag_t pm_flags = 0; mmc_pm_flag_t pm_flags = 0;
int i, ret; int i, ret;
@ -1666,14 +1667,19 @@ static int sdhci_pci_suspend(struct device *dev)
if (!slot) if (!slot)
continue; 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) if (ret)
goto err_pci_suspend; 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) 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; 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 pci_dev *pdev = to_pci_dev(dev);
struct sdhci_pci_chip *chip; struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot; struct sdhci_pci_slot *slot;
struct sdhci_host *host;
int i, ret; int i, ret;
chip = pci_get_drvdata(pdev); chip = pci_get_drvdata(pdev);
@ -1748,10 +1755,15 @@ static int sdhci_pci_runtime_suspend(struct device *dev)
if (!slot) if (!slot)
continue; continue;
ret = sdhci_runtime_suspend_host(slot->host); host = slot->host;
ret = sdhci_runtime_suspend_host(host);
if (ret) if (ret)
goto err_pci_runtime_suspend; 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) { 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->allow_runtime_pm = chip->fixes->allow_runtime_pm;
} }
chip->num_slots = slots; chip->num_slots = slots;
chip->pm_retune = true;
chip->rpm_retune = true;
pci_set_drvdata(pdev, chip); pci_set_drvdata(pdev, chip);

View File

@ -97,6 +97,8 @@ struct sdhci_pci_chip {
unsigned int quirks; unsigned int quirks;
unsigned int quirks2; unsigned int quirks2;
bool allow_runtime_pm; bool allow_runtime_pm;
bool pm_retune;
bool rpm_retune;
const struct sdhci_pci_fixes *fixes; const struct sdhci_pci_fixes *fixes;
int num_slots; /* Slots on controller */ int num_slots; /* Slots on controller */

View File

@ -213,6 +213,9 @@ static int sdhci_pltfm_suspend(struct device *dev)
{ {
struct sdhci_host *host = dev_get_drvdata(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); return sdhci_suspend_host(host);
} }

View File

@ -527,6 +527,8 @@ static int sdhci_pxav3_suspend(struct device *dev)
struct sdhci_host *host = dev_get_drvdata(dev); struct sdhci_host *host = dev_get_drvdata(dev);
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
ret = sdhci_suspend_host(host); ret = sdhci_suspend_host(host);
pm_runtime_mark_last_busy(dev); pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev); pm_runtime_put_autosuspend(dev);
@ -560,6 +562,9 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev)
if (ret) if (ret)
return ret; return ret;
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
clk_disable_unprepare(pxa->clk_io); clk_disable_unprepare(pxa->clk_io);
if (!IS_ERR(pxa->clk_core)) if (!IS_ERR(pxa->clk_core))
clk_disable_unprepare(pxa->clk_core); clk_disable_unprepare(pxa->clk_core);

View File

@ -743,6 +743,9 @@ static int sdhci_s3c_suspend(struct device *dev)
{ {
struct sdhci_host *host = dev_get_drvdata(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); return sdhci_suspend_host(host);
} }
@ -764,6 +767,9 @@ static int sdhci_s3c_runtime_suspend(struct device *dev)
ret = sdhci_runtime_suspend_host(host); ret = sdhci_runtime_suspend_host(host);
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
if (ourhost->cur_clk >= 0) if (ourhost->cur_clk >= 0)
clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
clk_disable_unprepare(busclk); clk_disable_unprepare(busclk);

View File

@ -237,6 +237,9 @@ static int sdhci_sirf_suspend(struct device *dev)
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
int ret; int ret;
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
ret = sdhci_suspend_host(host); ret = sdhci_suspend_host(host);
if (ret) if (ret)
return ret; return ret;

View File

@ -165,6 +165,9 @@ static int sdhci_suspend(struct device *dev)
struct spear_sdhci *sdhci = sdhci_priv(host); struct spear_sdhci *sdhci = sdhci_priv(host);
int ret; int ret;
if (host->tuning_mode != SDHCI_TUNING_MODE_3)
mmc_retune_needed(host->mmc);
ret = sdhci_suspend_host(host); ret = sdhci_suspend_host(host);
if (!ret) if (!ret)
clk_disable(sdhci->clk); clk_disable(sdhci->clk);

View File

@ -463,8 +463,12 @@ static int sdhci_st_suspend(struct device *dev)
struct sdhci_host *host = dev_get_drvdata(dev); struct sdhci_host *host = dev_get_drvdata(dev);
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_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) if (ret)
goto out; goto out;

View File

@ -2857,8 +2857,6 @@ int sdhci_suspend_host(struct sdhci_host *host)
sdhci_disable_card_detection(host); sdhci_disable_card_detection(host);
mmc_retune_timer_stop(host->mmc); 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))) { if (!device_may_wakeup(mmc_dev(host->mmc))) {
host->ier = 0; host->ier = 0;
@ -2919,8 +2917,6 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
unsigned long flags; unsigned long flags;
mmc_retune_timer_stop(host->mmc); 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); spin_lock_irqsave(&host->lock, flags);
host->ier &= SDHCI_INT_CARD_INT; host->ier &= SDHCI_INT_CARD_INT;