diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-of-at91.c')
-rw-r--r-- | drivers/mmc/host/sdhci-of-at91.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c index 83b684a3520b..4e47ed6bc716 100644 --- a/drivers/mmc/host/sdhci-of-at91.c +++ b/drivers/mmc/host/sdhci-of-at91.c @@ -42,6 +42,7 @@ struct sdhci_at91_priv { struct clk *hclock; struct clk *gck; struct clk *mainck; + bool restore_needed; }; static void sdhci_at91_set_force_card_detect(struct sdhci_host *host) @@ -224,6 +225,22 @@ static int sdhci_at91_set_clks_presets(struct device *dev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int sdhci_at91_suspend(struct device *dev) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host); + int ret; + + ret = pm_runtime_force_suspend(dev); + + priv->restore_needed = true; + + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + #ifdef CONFIG_PM static int sdhci_at91_runtime_suspend(struct device *dev) { @@ -251,6 +268,15 @@ static int sdhci_at91_runtime_resume(struct device *dev) struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host); int ret; + if (priv->restore_needed) { + ret = sdhci_at91_set_clks_presets(dev); + if (ret) + return ret; + + priv->restore_needed = false; + goto out; + } + ret = clk_prepare_enable(priv->mainck); if (ret) { dev_err(dev, "can't enable mainck\n"); @@ -269,13 +295,13 @@ static int sdhci_at91_runtime_resume(struct device *dev) return ret; } +out: return sdhci_runtime_resume_host(host); } #endif /* CONFIG_PM */ static const struct dev_pm_ops sdhci_at91_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SET_SYSTEM_SLEEP_PM_OPS(sdhci_at91_suspend, pm_runtime_force_resume) SET_RUNTIME_PM_OPS(sdhci_at91_runtime_suspend, sdhci_at91_runtime_resume, NULL) @@ -324,6 +350,8 @@ static int sdhci_at91_probe(struct platform_device *pdev) if (ret) goto sdhci_pltfm_free; + priv->restore_needed = false; + ret = mmc_of_parse(host->mmc); if (ret) goto clocks_disable_unprepare; |