mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Chancel Liu <chancel.liu@oss.nxp.com>
To: Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	Charles Keepax <ckeepax@opensource.cirrus.com>,
	Oder Chiou <oder_chiou@realtek.com>,
	Cezary Rojewski <cezary.rojewski@intel.com>
Cc: Support Opensource <support.opensource@diasemi.com>,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
	patches@opensource.cirrus.com
Subject: [PATCH v2 03/21] ASoC: codecs: tlv320aic32x4: Fix clock leak from runtime callbacks
Date: Wed, 23 Sep 2026 15:12:47 +0900	[thread overview]
Message-ID: <20260923061305.4041197-4-chancel.liu@oss.nxp.com> (raw)
In-Reply-To: <20260923061305.4041197-1-chancel.liu@oss.nxp.com>

From: Chancel Liu <chancel.liu@nxp.com>

component->dev is the underlying I2C/SPI device. The driver acquired
its codec clocks with devm_clk_get()/devm_clk_bulk_get(component->dev,
...) from the DAI set_sysclk runtime callback, from set_bias_level and
from the component .probe. Because devres on component->dev is only
released when the platform device is removed, each card bind/unbind
(and, for set_sysclk, each runtime invocation) leaked a fresh clock
reference.

Acquire all codec clocks once in the bus probe with a single
devm_clk_bulk_get() into the private struct, and have the runtime
callbacks and both component probes reuse those stored references.

Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
---
 sound/soc/codecs/tlv320aic32x4.c | 94 +++++++++++++++-----------------
 1 file changed, 44 insertions(+), 50 deletions(-)

diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index af4be5bee723..7fec94768afb 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -48,8 +48,18 @@ struct aic32x4_priv {
 	enum aic32x4_type type;
 
 	unsigned int fmt;
+
+	struct clk_bulk_data clocks[7];
 };
 
+#define AIC32X4_CLK_CODEC_CLKIN	0
+#define AIC32X4_CLK_PLL		1
+#define AIC32X4_CLK_NADC	2
+#define AIC32X4_CLK_MADC	3
+#define AIC32X4_CLK_NDAC	4
+#define AIC32X4_CLK_MDAC	5
+#define AIC32X4_CLK_BDIV	6
+
 static int aic32x4_reset_adc(struct snd_soc_dapm_widget *w,
 			     struct snd_kcontrol *kcontrol, int event)
 {
@@ -591,14 +601,10 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 				  int clk_id, unsigned int freq, int dir)
 {
 	struct snd_soc_component *component = codec_dai->component;
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	struct clk *mclk;
-	struct clk *pll;
-
-	pll = devm_clk_get(component->dev, "pll");
-	if (IS_ERR(pll))
-		return PTR_ERR(pll);
 
-	mclk = clk_get_parent(pll);
+	mclk = clk_get_parent(aic32x4->clocks[AIC32X4_CLK_PLL].clk);
 
 	return clk_set_rate(mclk, freq);
 }
@@ -750,17 +756,7 @@ static int aic32x4_setup_clocks(struct snd_soc_component *component,
 	unsigned long adc_clock_rate, dac_clock_rate;
 	int ret;
 
-	struct clk_bulk_data clocks[] = {
-		{ .id = "pll" },
-		{ .id = "nadc" },
-		{ .id = "madc" },
-		{ .id = "ndac" },
-		{ .id = "mdac" },
-		{ .id = "bdiv" },
-	};
-	ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks);
-	if (ret)
-		return ret;
+	struct clk_bulk_data *clocks = &aic32x4->clocks[AIC32X4_CLK_PLL];
 
 	ret = aic32x4_configure_rate(component, sample_rate, &aosr,
 				     &adc_resource_class, &dac_resource_class,
@@ -876,18 +872,15 @@ static int aic32x4_set_bias_level(struct snd_soc_component *component,
 				  enum snd_soc_bias_level level)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
+	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	int ret;
 
 	struct clk_bulk_data clocks[] = {
-		{ .id = "madc" },
-		{ .id = "mdac" },
-		{ .id = "bdiv" },
+		aic32x4->clocks[AIC32X4_CLK_MADC],
+		aic32x4->clocks[AIC32X4_CLK_MDAC],
+		aic32x4->clocks[AIC32X4_CLK_BDIV],
 	};
 
-	ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks);
-	if (ret)
-		return ret;
-
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks);
@@ -970,23 +963,16 @@ static int aic32x4_component_probe(struct snd_soc_component *component)
 {
 	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	u32 tmp_reg;
-	int ret;
 
-	struct clk_bulk_data clocks[] = {
-		{ .id = "codec_clkin" },
-		{ .id = "pll" },
-		{ .id = "bdiv" },
-		{ .id = "mdac" },
-	};
-
-	ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks);
-	if (ret)
-		return ret;
+	struct clk *codec_clkin = aic32x4->clocks[AIC32X4_CLK_CODEC_CLKIN].clk;
+	struct clk *pll = aic32x4->clocks[AIC32X4_CLK_PLL].clk;
+	struct clk *bdiv = aic32x4->clocks[AIC32X4_CLK_BDIV].clk;
+	struct clk *mdac = aic32x4->clocks[AIC32X4_CLK_MDAC].clk;
 
 	aic32x4_setup_gpios(component);
 
-	clk_set_parent(clocks[0].clk, clocks[1].clk);
-	clk_set_parent(clocks[2].clk, clocks[3].clk);
+	clk_set_parent(codec_clkin, pll);
+	clk_set_parent(bdiv, mdac);
 
 	/* Power platform configuration */
 	if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
@@ -1127,23 +1113,16 @@ static int aic32x4_tas2505_component_probe(struct snd_soc_component *component)
 {
 	struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
 	u32 tmp_reg;
-	int ret;
-
-	struct clk_bulk_data clocks[] = {
-		{ .id = "codec_clkin" },
-		{ .id = "pll" },
-		{ .id = "bdiv" },
-		{ .id = "mdac" },
-	};
 
-	ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks);
-	if (ret)
-		return ret;
+	struct clk *codec_clkin = aic32x4->clocks[AIC32X4_CLK_CODEC_CLKIN].clk;
+	struct clk *pll = aic32x4->clocks[AIC32X4_CLK_PLL].clk;
+	struct clk *bdiv = aic32x4->clocks[AIC32X4_CLK_BDIV].clk;
+	struct clk *mdac = aic32x4->clocks[AIC32X4_CLK_MDAC].clk;
 
 	aic32x4_setup_gpios(component);
 
-	clk_set_parent(clocks[0].clk, clocks[1].clk);
-	clk_set_parent(clocks[2].clk, clocks[3].clk);
+	clk_set_parent(codec_clkin, pll);
+	clk_set_parent(bdiv, mdac);
 
 	/* Power platform configuration */
 	if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
@@ -1362,6 +1341,21 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap,
 	if (ret)
 		goto err_disable_regulators;
 
+	aic32x4->clocks[AIC32X4_CLK_CODEC_CLKIN].id = "codec_clkin";
+	aic32x4->clocks[AIC32X4_CLK_PLL].id = "pll";
+	aic32x4->clocks[AIC32X4_CLK_NADC].id = "nadc";
+	aic32x4->clocks[AIC32X4_CLK_MADC].id = "madc";
+	aic32x4->clocks[AIC32X4_CLK_NDAC].id = "ndac";
+	aic32x4->clocks[AIC32X4_CLK_MDAC].id = "mdac";
+	aic32x4->clocks[AIC32X4_CLK_BDIV].id = "bdiv";
+
+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(aic32x4->clocks),
+				aic32x4->clocks);
+	if (ret) {
+		dev_err(dev, "Failed to get clocks\n");
+		goto err_disable_regulators;
+	}
+
 	switch (aic32x4->type) {
 	case AIC32X4_TYPE_TAS2505:
 		ret = devm_snd_soc_register_component(dev,
-- 
2.50.1


  parent reply	other threads:[~2026-09-23  6:13 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23  6:12 [PATCH v2 00/21] ASoC: codecs: Fix resource leaks across card bind/unbind Chancel Liu
2026-09-23  6:12 ` [PATCH v2 01/21] ASoC: codecs: cpcap: Fix devm " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 02/21] ASoC: codecs: da7218: " Chancel Liu
2026-09-23  6:12 ` Chancel Liu [this message]
2026-09-23  6:12 ` [PATCH v2 04/21] ASoC: codecs: twl4030: Acquire board params and hs_extmute GPIO in the platform probe Chancel Liu
2026-09-23  6:12 ` [PATCH v2 05/21] ASoC: codecs: es8316: Move mclk acquisition to the i2c probe Chancel Liu
2026-09-23  8:19   ` Cezary Rojewski
2026-09-23  6:12 ` [PATCH v2 06/21] ASoC: codecs: es8323: " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 07/21] ASoC: codecs: es8311: " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 08/21] ASoC: codecs: es8328: Move clk acquisition to the bus probe Chancel Liu
2026-09-23  6:12 ` [PATCH v2 09/21] ASoC: codecs: rt5640: Move mclk acquisition to the i2c probe Chancel Liu
2026-09-23  8:16   ` Cezary Rojewski
2026-09-23  8:22     ` Chancel Liu
2026-09-23  6:12 ` [PATCH v2 10/21] ASoC: codecs: rt5616: " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 11/21] ASoC: codecs: rt5514: Move clk " Chancel Liu
2026-09-23  8:19   ` Cezary Rojewski
2026-09-23  6:12 ` [PATCH v2 12/21] ASoC: codecs: rt5682s: Move mclk " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 13/21] ASoC: codecs: max98090: " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 14/21] ASoC: codecs: max98095: " Chancel Liu
2026-09-23  6:12 ` [PATCH v2 15/21] ASoC: codecs: wm8985: Move regulator acquisition to the bus probe Chancel Liu
2026-09-23  8:56   ` Charles Keepax
2026-09-23  6:13 ` [PATCH v2 16/21] ASoC: codecs: wm8955: Move regulator acquisition to the i2c probe Chancel Liu
2026-09-23  6:13 ` [PATCH v2 17/21] ASoC: codecs: es8389: Move regulator and mclk " Chancel Liu
2026-09-23  6:13 ` [PATCH v2 18/21] ASoC: codecs: rt5677-spi: Free the DSP context on component remove Chancel Liu
2026-09-23  6:13 ` [PATCH v2 19/21] ASoC: codecs: rt1011: Free the bq/drc coefficient arrays " Chancel Liu
2026-09-23  6:13 ` [PATCH v2 20/21] ASoC: codecs: rt5645: Free the hardware EQ parameters " Chancel Liu
2026-09-23  6:13 ` [PATCH v2 21/21] ASoC: codecs: rt5514-spi: Free the DSP context " Chancel Liu
2026-09-23 12:27 ` [PATCH v2 00/21] ASoC: codecs: Fix resource leaks across card bind/unbind Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260923061305.4041197-4-chancel.liu@oss.nxp.com \
    --to=chancel.liu@oss.nxp.com \
    --cc=broonie@kernel.org \
    --cc=cezary.rojewski@intel.com \
    --cc=ckeepax@opensource.cirrus.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=oder_chiou@realtek.com \
    --cc=patches@opensource.cirrus.com \
    --cc=perex@perex.cz \
    --cc=support.opensource@diasemi.com \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®