Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: fsl_ssi: refine ipg clock usage in this module

Check if ipg clock is in clock-names property, then we can move the
ipg clock enable and disable operation to startup and shutdown, that
is only enable ipg clock when ssi is working and keep clock is disabled
when ssi is in idle.
But when the checking is failed, remain the clock control as before.

Tested-by: Markus Pargmann <mpa@pengutronix.de>
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Shengjiu Wang and committed by
Mark Brown
f4a43cab cf4f7fc3

+45 -8
+45 -8
sound/soc/fsl/fsl_ssi.c
··· 169 169 u8 i2s_mode; 170 170 bool use_dma; 171 171 bool use_dual_fifo; 172 + bool has_ipg_clk_name; 172 173 unsigned int fifo_depth; 173 174 struct fsl_ssi_rxtx_reg_val rxtx_reg_val; 174 175 ··· 531 530 struct snd_soc_pcm_runtime *rtd = substream->private_data; 532 531 struct fsl_ssi_private *ssi_private = 533 532 snd_soc_dai_get_drvdata(rtd->cpu_dai); 533 + int ret; 534 + 535 + ret = clk_prepare_enable(ssi_private->clk); 536 + if (ret) 537 + return ret; 534 538 535 539 /* When using dual fifo mode, it is safer to ensure an even period 536 540 * size. If appearing to an odd number while DMA always starts its ··· 547 541 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); 548 542 549 543 return 0; 544 + } 545 + 546 + /** 547 + * fsl_ssi_shutdown: shutdown the SSI 548 + * 549 + */ 550 + static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, 551 + struct snd_soc_dai *dai) 552 + { 553 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 554 + struct fsl_ssi_private *ssi_private = 555 + snd_soc_dai_get_drvdata(rtd->cpu_dai); 556 + 557 + clk_disable_unprepare(ssi_private->clk); 558 + 550 559 } 551 560 552 561 /** ··· 1064 1043 1065 1044 static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { 1066 1045 .startup = fsl_ssi_startup, 1046 + .shutdown = fsl_ssi_shutdown, 1067 1047 .hw_params = fsl_ssi_hw_params, 1068 1048 .hw_free = fsl_ssi_hw_free, 1069 1049 .set_fmt = fsl_ssi_set_dai_fmt, ··· 1190 1168 u32 dmas[4]; 1191 1169 int ret; 1192 1170 1193 - ssi_private->clk = devm_clk_get(&pdev->dev, NULL); 1171 + if (ssi_private->has_ipg_clk_name) 1172 + ssi_private->clk = devm_clk_get(&pdev->dev, "ipg"); 1173 + else 1174 + ssi_private->clk = devm_clk_get(&pdev->dev, NULL); 1194 1175 if (IS_ERR(ssi_private->clk)) { 1195 1176 ret = PTR_ERR(ssi_private->clk); 1196 1177 dev_err(&pdev->dev, "could not get clock: %d\n", ret); 1197 1178 return ret; 1198 1179 } 1199 1180 1200 - ret = clk_prepare_enable(ssi_private->clk); 1201 - if (ret) { 1202 - dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); 1203 - return ret; 1181 + if (!ssi_private->has_ipg_clk_name) { 1182 + ret = clk_prepare_enable(ssi_private->clk); 1183 + if (ret) { 1184 + dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); 1185 + return ret; 1186 + } 1204 1187 } 1205 1188 1206 1189 /* For those SLAVE implementations, we ingore non-baudclk cases ··· 1263 1236 return 0; 1264 1237 1265 1238 error_pcm: 1266 - clk_disable_unprepare(ssi_private->clk); 1267 1239 1240 + if (!ssi_private->has_ipg_clk_name) 1241 + clk_disable_unprepare(ssi_private->clk); 1268 1242 return ret; 1269 1243 } 1270 1244 ··· 1274 1246 { 1275 1247 if (!ssi_private->use_dma) 1276 1248 imx_pcm_fiq_exit(pdev); 1277 - clk_disable_unprepare(ssi_private->clk); 1249 + if (!ssi_private->has_ipg_clk_name) 1250 + clk_disable_unprepare(ssi_private->clk); 1278 1251 } 1279 1252 1280 1253 static int fsl_ssi_probe(struct platform_device *pdev) ··· 1350 1321 return -ENOMEM; 1351 1322 } 1352 1323 1353 - ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, 1324 + ret = of_property_match_string(np, "clock-names", "ipg"); 1325 + if (ret < 0) { 1326 + ssi_private->has_ipg_clk_name = false; 1327 + ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, 1354 1328 &fsl_ssi_regconfig); 1329 + } else { 1330 + ssi_private->has_ipg_clk_name = true; 1331 + ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev, 1332 + "ipg", iomem, &fsl_ssi_regconfig); 1333 + } 1355 1334 if (IS_ERR(ssi_private->regs)) { 1356 1335 dev_err(&pdev->dev, "Failed to init register map\n"); 1357 1336 return PTR_ERR(ssi_private->regs);