aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2015-01-14 13:42:32 -0500
committerMark Brown <broonie@kernel.org>2015-01-14 14:46:54 -0500
commitc92f1d0e7c8431f8b3bf1d42e951ead07b22078e (patch)
tree34610e9af7418bda138f21cad664bd4ef20bee42
parent0ec2ba807c1563134a865b6f0b326b8a2e776937 (diff)
ASoC: samsung: i2s: Move clk enable to the platform driver probe()
The clk_prepare_enable() call on the "iis" clock is moved to happen earlier in the DAI platform device driver's probe() callback, so the I2S registers can be safely accessed through the clk API, after the clk supplier is registered in the platform device probe(). After this patch the "iis" clock is kept enabled since the (primary) I2S platform device probe() and until the platform device driver remove() call. This is similar to gating the clock in the snd_soc_dai probe() and remove() callbacks. Normally, in addition to that we should mark the device as PM runtime active, so if runtime PM is enabled it can idle the device by turning off the clock. Correcting this issue is left for a separate patch series, as we need to ensure the BUSCLK clock is always enabled when required. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/samsung/i2s.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index a854ffca2416..f75c19e5b5c3 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -969,7 +969,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
969{ 969{
970 struct i2s_dai *i2s = to_info(dai); 970 struct i2s_dai *i2s = to_info(dai);
971 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; 971 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
972 int ret;
973 972
974 if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */ 973 if (is_secondary(i2s)) { /* If this is probe on the secondary DAI */
975 samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, 974 samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback,
@@ -977,12 +976,6 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
977 goto probe_exit; 976 goto probe_exit;
978 } 977 }
979 978
980 ret = clk_prepare_enable(i2s->clk);
981 if (ret != 0) {
982 dev_err(&i2s->pdev->dev, "failed to enable clock: %d\n", ret);
983 return ret;
984 }
985
986 samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); 979 samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
987 980
988 if (i2s->quirks & QUIRK_NEED_RSTCLR) 981 if (i2s->quirks & QUIRK_NEED_RSTCLR)
@@ -1014,18 +1007,12 @@ probe_exit:
1014static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) 1007static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
1015{ 1008{
1016 struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); 1009 struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
1017 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
1018
1019 if (!other || !other->clk) {
1020 1010
1011 if (!is_secondary(i2s)) {
1021 if (i2s->quirks & QUIRK_NEED_RSTCLR) 1012 if (i2s->quirks & QUIRK_NEED_RSTCLR)
1022 writel(0, i2s->addr + I2SCON); 1013 writel(0, i2s->addr + I2SCON);
1023
1024 clk_disable_unprepare(i2s->clk);
1025 } 1014 }
1026 1015
1027 i2s->clk = NULL;
1028
1029 return 0; 1016 return 0;
1030} 1017}
1031 1018
@@ -1139,6 +1126,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1139 u32 regs_base, quirks = 0, idma_addr = 0; 1126 u32 regs_base, quirks = 0, idma_addr = 0;
1140 struct device_node *np = pdev->dev.of_node; 1127 struct device_node *np = pdev->dev.of_node;
1141 const struct samsung_i2s_dai_data *i2s_dai_data; 1128 const struct samsung_i2s_dai_data *i2s_dai_data;
1129 int ret;
1142 1130
1143 /* Call during Seconday interface registration */ 1131 /* Call during Seconday interface registration */
1144 i2s_dai_data = samsung_i2s_get_driver_data(pdev); 1132 i2s_dai_data = samsung_i2s_get_driver_data(pdev);
@@ -1216,6 +1204,12 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1216 dev_err(&pdev->dev, "Failed to get iis clock\n"); 1204 dev_err(&pdev->dev, "Failed to get iis clock\n");
1217 return PTR_ERR(pri_dai->clk); 1205 return PTR_ERR(pri_dai->clk);
1218 } 1206 }
1207
1208 ret = clk_prepare_enable(pri_dai->clk);
1209 if (ret != 0) {
1210 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
1211 return ret;
1212 }
1219 pri_dai->dma_playback.dma_addr = regs_base + I2STXD; 1213 pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
1220 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; 1214 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
1221 pri_dai->dma_playback.ch_name = "tx"; 1215 pri_dai->dma_playback.ch_name = "tx";
@@ -1286,6 +1280,9 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1286 pm_runtime_disable(&pdev->dev); 1280 pm_runtime_disable(&pdev->dev);
1287 } 1281 }
1288 1282
1283 if (!is_secondary(i2s))
1284 clk_disable_unprepare(i2s->clk);
1285
1289 i2s->pri_dai = NULL; 1286 i2s->pri_dai = NULL;
1290 i2s->sec_dai = NULL; 1287 i2s->sec_dai = NULL;
1291 1288