aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-12-29 06:34:05 -0500
committerMark Brown <broonie@kernel.org>2016-12-31 13:36:20 -0500
commite7e52dfc68a2160570c7ec51415e391961160edb (patch)
treed565526047b972ddd07c5eb6970ce2e379e6f6fd
parentdc938ddb56283a0b71d987e7ecd4be90390985d6 (diff)
ASoC: samsung: i2s: Move saving and restoring regs to runtime pm operations
This patch moves saving and restoring I2S registers to runtime PM operations, what prepares the driver to operate with audio power domain. When support for audio power domain is enabled and the domain is being turned off, the I2S module will loose its context (registers), so runtime callbacks have to handle it. System sleep suspend/resume operation are implemented on top of runtime PM operations with generic pm_runtime_force_suspend/resume helpers. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/samsung/i2s.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 8d8965e7107c..df3fae862665 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -983,24 +983,12 @@ i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
983#ifdef CONFIG_PM 983#ifdef CONFIG_PM
984static int i2s_suspend(struct snd_soc_dai *dai) 984static int i2s_suspend(struct snd_soc_dai *dai)
985{ 985{
986 struct i2s_dai *i2s = to_info(dai); 986 return pm_runtime_force_suspend(dai->dev);
987
988 i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
989 i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
990 i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
991
992 return 0;
993} 987}
994 988
995static int i2s_resume(struct snd_soc_dai *dai) 989static int i2s_resume(struct snd_soc_dai *dai)
996{ 990{
997 struct i2s_dai *i2s = to_info(dai); 991 return pm_runtime_force_resume(dai->dev);
998
999 writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
1000 writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
1001 writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
1002
1003 return 0;
1004} 992}
1005#else 993#else
1006#define i2s_suspend NULL 994#define i2s_suspend NULL
@@ -1129,6 +1117,10 @@ static int i2s_runtime_suspend(struct device *dev)
1129{ 1117{
1130 struct i2s_dai *i2s = dev_get_drvdata(dev); 1118 struct i2s_dai *i2s = dev_get_drvdata(dev);
1131 1119
1120 i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
1121 i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
1122 i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
1123
1132 clk_disable_unprepare(i2s->clk); 1124 clk_disable_unprepare(i2s->clk);
1133 1125
1134 return 0; 1126 return 0;
@@ -1140,6 +1132,10 @@ static int i2s_runtime_resume(struct device *dev)
1140 1132
1141 clk_prepare_enable(i2s->clk); 1133 clk_prepare_enable(i2s->clk);
1142 1134
1135 writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
1136 writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
1137 writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
1138
1143 return 0; 1139 return 0;
1144} 1140}
1145#endif /* CONFIG_PM */ 1141#endif /* CONFIG_PM */
@@ -1510,6 +1506,8 @@ MODULE_DEVICE_TABLE(of, exynos_i2s_match);
1510static const struct dev_pm_ops samsung_i2s_pm = { 1506static const struct dev_pm_ops samsung_i2s_pm = {
1511 SET_RUNTIME_PM_OPS(i2s_runtime_suspend, 1507 SET_RUNTIME_PM_OPS(i2s_runtime_suspend,
1512 i2s_runtime_resume, NULL) 1508 i2s_runtime_resume, NULL)
1509 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1510 pm_runtime_force_resume)
1513}; 1511};
1514 1512
1515static struct platform_driver samsung_i2s_driver = { 1513static struct platform_driver samsung_i2s_driver = {