[PATCH 0/6] ASoC: fsl: Don't use devm_regmap_init_mmio_clk
When there is power domain bind with ipg clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk.
Shengjiu Wang (6): ASoC: fsl_esai: Don't use devm_regmap_init_mmio_clk ASoC: fsl_spdif: Don't use devm_regmap_init_mmio_clk ASoC: fsl_asrc: Don't use devm_regmap_init_mmio_clk ASoC: fsl_easrc: Don't use devm_regmap_init_mmio_clk ASoC: fsl_audmix: Don't use devm_regmap_init_mmio_clk ASoC: fsl_micfil: Don't use devm_regmap_init_mmio_clk
sound/soc/fsl/fsl_asrc.c | 57 +++++++++++++++++++++++++++++--------- sound/soc/fsl/fsl_audmix.c | 3 +- sound/soc/fsl/fsl_easrc.c | 3 +- sound/soc/fsl/fsl_esai.c | 48 ++++++++++++++++++++++++-------- sound/soc/fsl/fsl_micfil.c | 25 +++++++++++++---- sound/soc/fsl/fsl_spdif.c | 3 +- 6 files changed, 103 insertions(+), 36 deletions(-)
When there is power domain bind with bus clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk,but explicitly enable clock when it is used.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com --- sound/soc/fsl/fsl_esai.c | 48 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 41b154417b92..c0d4f3c5dbb1 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -945,6 +945,9 @@ static const struct regmap_config fsl_esai_regmap_config = { .cache_type = REGCACHE_FLAT, };
+static int fsl_esai_runtime_resume(struct device *dev); +static int fsl_esai_runtime_suspend(struct device *dev); + static int fsl_esai_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -969,8 +972,7 @@ static int fsl_esai_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs);
- esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "core", regs, &fsl_esai_regmap_config); + esai_priv->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_esai_regmap_config); if (IS_ERR(esai_priv->regmap)) { dev_err(&pdev->dev, "failed to init regmap: %ld\n", PTR_ERR(esai_priv->regmap)); @@ -1039,11 +1041,23 @@ static int fsl_esai_probe(struct platform_device *pdev) }
dev_set_drvdata(&pdev->dev, esai_priv); - spin_lock_init(&esai_priv->lock); + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) { + ret = fsl_esai_runtime_resume(&pdev->dev); + if (ret) + goto err_pm_disable; + } + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&pdev->dev); + goto err_pm_get_sync; + } + ret = fsl_esai_hw_init(esai_priv); if (ret) - return ret; + goto err_pm_get_sync;
esai_priv->tx_mask = 0xFFFFFFFF; esai_priv->rx_mask = 0xFFFFFFFF; @@ -1054,24 +1068,33 @@ static int fsl_esai_probe(struct platform_device *pdev) regmap_write(esai_priv->regmap, REG_ESAI_RSMA, 0); regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
+ ret = pm_runtime_put_sync(&pdev->dev); + if (ret < 0) + goto err_pm_get_sync; + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, &fsl_esai_dai, 1); if (ret) { dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); - return ret; + goto err_pm_get_sync; }
INIT_WORK(&esai_priv->work, fsl_esai_hw_reset);
- pm_runtime_enable(&pdev->dev); - - regcache_cache_only(esai_priv->regmap, true); - ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE); - if (ret) + if (ret) { dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret); + goto err_pm_get_sync; + }
return ret; + +err_pm_get_sync: + if (!pm_runtime_status_suspended(&pdev->dev)) + fsl_esai_runtime_suspend(&pdev->dev); +err_pm_disable: + pm_runtime_disable(&pdev->dev); + return ret; }
static int fsl_esai_remove(struct platform_device *pdev) @@ -1079,6 +1102,9 @@ static int fsl_esai_remove(struct platform_device *pdev) struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + fsl_esai_runtime_suspend(&pdev->dev); + cancel_work_sync(&esai_priv->work);
return 0; @@ -1092,7 +1118,6 @@ static const struct of_device_id fsl_esai_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
-#ifdef CONFIG_PM static int fsl_esai_runtime_resume(struct device *dev) { struct fsl_esai *esai = dev_get_drvdata(dev); @@ -1160,7 +1185,6 @@ static int fsl_esai_runtime_suspend(struct device *dev)
return 0; } -#endif /* CONFIG_PM */
static const struct dev_pm_ops fsl_esai_pm_ops = { SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
When there is power domain bind with core clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk,but explicitly enable clock when it is used.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com --- sound/soc/fsl/fsl_spdif.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 1cd3441d1c03..c631de325a6e 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1294,8 +1294,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs);
- spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "core", regs, &fsl_spdif_regmap_config); + spdif_priv->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_spdif_regmap_config); if (IS_ERR(spdif_priv->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); return PTR_ERR(spdif_priv->regmap);
When there is power domain bind with mem clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk,but explicitly enable clock when it is used.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com --- sound/soc/fsl/fsl_asrc.c | 57 +++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 13 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 63d236ef5c4d..0e1ad8efebd3 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -1008,6 +1008,9 @@ static int fsl_asrc_get_fifo_addr(u8 dir, enum asrc_pair_index index) return REG_ASRDx(dir, index); }
+static int fsl_asrc_runtime_resume(struct device *dev); +static int fsl_asrc_runtime_suspend(struct device *dev); + static int fsl_asrc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1039,8 +1042,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
asrc->paddr = res->start;
- asrc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "mem", regs, - &fsl_asrc_regmap_config); + asrc->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &fsl_asrc_regmap_config); if (IS_ERR(asrc->regmap)) { dev_err(&pdev->dev, "failed to init regmap\n"); return PTR_ERR(asrc->regmap); @@ -1117,12 +1119,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) } }
- ret = fsl_asrc_init(asrc); - if (ret) { - dev_err(&pdev->dev, "failed to init asrc %d\n", ret); - return ret; - } - asrc->channel_avail = 10;
ret = of_property_read_u32(np, "fsl,asrc-rate", @@ -1161,21 +1157,56 @@ static int fsl_asrc_probe(struct platform_device *pdev) }
platform_set_drvdata(pdev, asrc); - pm_runtime_enable(&pdev->dev); spin_lock_init(&asrc->lock); - regcache_cache_only(asrc->regmap, true); + pm_runtime_enable(&pdev->dev); + if (!pm_runtime_enabled(&pdev->dev)) { + ret = fsl_asrc_runtime_resume(&pdev->dev); + if (ret) + goto err_pm_disable; + } + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&pdev->dev); + goto err_pm_get_sync; + } + + ret = fsl_asrc_init(asrc); + if (ret) { + dev_err(&pdev->dev, "failed to init asrc %d\n", ret); + goto err_pm_get_sync; + } + + ret = pm_runtime_put_sync(&pdev->dev); + if (ret < 0) + goto err_pm_get_sync;
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, &fsl_asrc_dai, 1); if (ret) { dev_err(&pdev->dev, "failed to register ASoC DAI\n"); - return ret; + goto err_pm_get_sync; }
return 0; + +err_pm_get_sync: + if (!pm_runtime_status_suspended(&pdev->dev)) + fsl_asrc_runtime_suspend(&pdev->dev); +err_pm_disable: + pm_runtime_disable(&pdev->dev); + return ret; +} + +static int fsl_asrc_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + fsl_asrc_runtime_suspend(&pdev->dev); + + return 0; }
-#ifdef CONFIG_PM static int fsl_asrc_runtime_resume(struct device *dev) { struct fsl_asrc *asrc = dev_get_drvdata(dev); @@ -1252,7 +1283,6 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
return 0; } -#endif /* CONFIG_PM */
static const struct dev_pm_ops fsl_asrc_pm = { SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, NULL) @@ -1291,6 +1321,7 @@ MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
static struct platform_driver fsl_asrc_driver = { .probe = fsl_asrc_probe, + .remove = fsl_asrc_remove, .driver = { .name = "fsl-asrc", .of_match_table = fsl_asrc_ids,
When there is power domain bind with mem clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk,but explicitly enable clock when it is used.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com --- sound/soc/fsl/fsl_easrc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index 600e0d670ca6..5e33afe87c4a 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -1896,8 +1896,7 @@ static int fsl_easrc_probe(struct platform_device *pdev)
easrc->paddr = res->start;
- easrc->regmap = devm_regmap_init_mmio_clk(dev, "mem", regs, - &fsl_easrc_regmap_config); + easrc->regmap = devm_regmap_init_mmio(dev, regs, &fsl_easrc_regmap_config); if (IS_ERR(easrc->regmap)) { dev_err(dev, "failed to init regmap"); return PTR_ERR(easrc->regmap);
When there is power domain bind with ipg clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk,but explicitly enable clock when it is used.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com --- sound/soc/fsl/fsl_audmix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c index 8dc44dec7956..f931288e256c 100644 --- a/sound/soc/fsl/fsl_audmix.c +++ b/sound/soc/fsl/fsl_audmix.c @@ -476,8 +476,7 @@ static int fsl_audmix_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs);
- priv->regmap = devm_regmap_init_mmio_clk(dev, "ipg", regs, - &fsl_audmix_regmap_config); + priv->regmap = devm_regmap_init_mmio(dev, regs, &fsl_audmix_regmap_config); if (IS_ERR(priv->regmap)) { dev_err(dev, "failed to init regmap\n"); return PTR_ERR(priv->regmap);
When there is power domain bind with ipg_clk clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
cause the power domain of clock always be enabled after regmap_init(). which impact the power consumption.
So use devm_regmap_init_mmio instead of devm_regmap_init_mmio_clk,but explicitly enable clock when it is used.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Reviewed-by: Viorel Suman viorel.suman@nxp.com --- sound/soc/fsl/fsl_micfil.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 2b9edd4bb94d..3cf789ed6cbe 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -31,6 +31,7 @@ struct fsl_micfil { struct platform_device *pdev; struct regmap *regmap; const struct fsl_micfil_soc_data *soc; + struct clk *busclk; struct clk *mclk; struct snd_dmaengine_dai_dma_data dma_params_rx; unsigned int dataline; @@ -660,16 +661,22 @@ static int fsl_micfil_probe(struct platform_device *pdev) return PTR_ERR(micfil->mclk); }
+ micfil->busclk = devm_clk_get(&pdev->dev, "ipg_clk"); + if (IS_ERR(micfil->busclk)) { + dev_err(&pdev->dev, "failed to get ipg clock: %ld\n", + PTR_ERR(micfil->busclk)); + return PTR_ERR(micfil->busclk); + } + /* init regmap */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(regs)) return PTR_ERR(regs);
- micfil->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "ipg_clk", - regs, - &fsl_micfil_regmap_config); + micfil->regmap = devm_regmap_init_mmio(&pdev->dev, + regs, + &fsl_micfil_regmap_config); if (IS_ERR(micfil->regmap)) { dev_err(&pdev->dev, "failed to init MICFIL regmap: %ld\n", PTR_ERR(micfil->regmap)); @@ -729,6 +736,7 @@ static int fsl_micfil_probe(struct platform_device *pdev) platform_set_drvdata(pdev, micfil);
pm_runtime_enable(&pdev->dev); + regcache_cache_only(micfil->regmap, true);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component, &fsl_micfil_dai, 1); @@ -752,6 +760,7 @@ static int __maybe_unused fsl_micfil_runtime_suspend(struct device *dev) regcache_cache_only(micfil->regmap, true);
clk_disable_unprepare(micfil->mclk); + clk_disable_unprepare(micfil->busclk);
return 0; } @@ -761,10 +770,16 @@ static int __maybe_unused fsl_micfil_runtime_resume(struct device *dev) struct fsl_micfil *micfil = dev_get_drvdata(dev); int ret;
- ret = clk_prepare_enable(micfil->mclk); + ret = clk_prepare_enable(micfil->busclk); if (ret < 0) return ret;
+ ret = clk_prepare_enable(micfil->mclk); + if (ret < 0) { + clk_disable_unprepare(micfil->busclk); + return ret; + } + regcache_cache_only(micfil->regmap, false); regcache_mark_dirty(micfil->regmap); regcache_sync(micfil->regmap);
On Wed, 24 Mar 2021 17:58:42 +0800, Shengjiu Wang wrote:
When there is power domain bind with ipg clock,
The call flow: devm_regmap_init_mmio_clk - clk_prepare() - clk_pm_runtime_get()
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/6] ASoC: fsl_esai: Don't use devm_regmap_init_mmio_clk commit: 203773e39347922b3923df6094324d430664466e [2/6] ASoC: fsl_spdif: Don't use devm_regmap_init_mmio_clk commit: c2562572467a74fd637d2d22fb773b052512528c [3/6] ASoC: fsl_asrc: Don't use devm_regmap_init_mmio_clk commit: cab04ab5900fea6655f2a49d1f94c37200b63a59 [4/6] ASoC: fsl_easrc: Don't use devm_regmap_init_mmio_clk commit: 069b24f22eb9dba2e0886b40ea3feaa98e3f4f9b [5/6] ASoC: fsl_audmix: Don't use devm_regmap_init_mmio_clk commit: 3feaba79d8f701a774815483aa0e7f4edb15c880 [6/6] ASoC: fsl_micfil: Don't use devm_regmap_init_mmio_clk commit: b5cf28f7a890f3554ca15a43edbbb86dd1b9663c
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Shengjiu Wang