[PATCH v2] ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()

Ma Ke posted 1 patch 1 week, 3 days ago
There is a newer version of this series
sound/soc/codecs/wcd934x.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
[PATCH v2] ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()
Posted by Ma Ke 1 week, 3 days ago
wcd934x_codec_parse_data() contains a device reference count leak in
of_slim_get_device() where device_find_child() increases the reference
count of the device but this reference is not properly decreased in
the success path. Add put_device() in wcd934x_codec_parse_data() and
add devm_add_action_or_reset() in the probe function, which ensures
that the reference count of the device is correctly managed.

Memory leak in regmap_init_slimbus() as the allocated regmap is not
released when the device is removed. Using devm_regmap_init_slimbus()
instead of regmap_init_slimbus() to ensure automatic regmap cleanup on
device removal.

Calling path: of_slim_get_device() -> of_find_slim_device() ->
device_find_child(). As comment of device_find_child() says, 'NOTE:
you will need to drop the reference with put_device() after use.'.

Found by code review.

Cc: stable@vger.kernel.org
Fixes: a61f3b4f476e ("ASoC: wcd934x: add support to wcd9340/wcd9341 codec")
Signed-off-by: Ma Ke <make24@iscas.ac.cn>
---
Changes in v2:
- modified the handling in the success path and fixed the memory leak for regmap as suggestions.
---
 sound/soc/codecs/wcd934x.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
index 1bb7e1dc7e6b..b472320d1ca4 100644
--- a/sound/soc/codecs/wcd934x.c
+++ b/sound/soc/codecs/wcd934x.c
@@ -5847,11 +5847,13 @@ static int wcd934x_codec_parse_data(struct wcd934x_codec *wcd)
 		return dev_err_probe(dev, -EINVAL, "Unable to get SLIM Interface device\n");
 
 	slim_get_logical_addr(wcd->sidev);
-	wcd->if_regmap = regmap_init_slimbus(wcd->sidev,
+	wcd->if_regmap = devm_regmap_init_slimbus(wcd->sidev,
 				  &wcd934x_ifc_regmap_config);
-	if (IS_ERR(wcd->if_regmap))
+	if (IS_ERR(wcd->if_regmap)) {
+		put_device(&wcd->sidev->dev);
 		return dev_err_probe(dev, PTR_ERR(wcd->if_regmap),
 				     "Failed to allocate ifc register map\n");
+	}

 	of_property_read_u32(dev->parent->of_node, "qcom,dmic-sample-rate",
 			     &wcd->dmic_sample_rate);
@@ -5893,6 +5895,10 @@ static int wcd934x_codec_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;

+	ret = devm_add_action_or_reset(dev, (void (*)(void *))put_device, &wcd->sidev->dev);
+	if (ret)
+		return ret;
+
 	/* set default rate 9P6MHz */
 	regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
 			   WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
-- 
2.17.1
Re: [PATCH v2] ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()
Posted by kernel test robot 1 week, 2 days ago
Hi Ma,

kernel test robot noticed the following build warnings:

[auto build test WARNING on broonie-sound/for-next]
[also build test WARNING on linus/master v6.17-rc7 next-20250919]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ma-Ke/ASoC-wcd934x-fix-error-handling-in-wcd934x_codec_parse_data/20250922-094038
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
patch link:    https://lore.kernel.org/r/20250922013507.558-1-make24%40iscas.ac.cn
patch subject: [PATCH v2] ASoC: wcd934x: fix error handling in wcd934x_codec_parse_data()
config: i386-buildonly-randconfig-005-20250922 (https://download.01.org/0day-ci/archive/20250922/202509221535.es8PWacQ-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250922/202509221535.es8PWacQ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509221535.es8PWacQ-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> sound/soc/codecs/wcd934x.c:5862:38: warning: cast from 'void (*)(struct device *)' to 'void (*)(void *)' converts to incompatible function type [-Wcast-function-type-strict]
    5862 |         ret = devm_add_action_or_reset(dev, (void (*)(void *))put_device, &wcd->sidev->dev);
         |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device/devres.h:166:34: note: expanded from macro 'devm_add_action_or_reset'
     166 |         __devm_add_action_or_reset(dev, action, data, #action)
         |                                         ^~~~~~
   1 warning generated.


vim +5862 sound/soc/codecs/wcd934x.c

  5837	
  5838	static int wcd934x_codec_probe(struct platform_device *pdev)
  5839	{
  5840		struct device *dev = &pdev->dev;
  5841		struct wcd934x_ddata *data = dev_get_drvdata(dev->parent);
  5842		struct wcd934x_codec *wcd;
  5843		int ret, irq;
  5844	
  5845		wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
  5846		if (!wcd)
  5847			return -ENOMEM;
  5848	
  5849		wcd->dev = dev;
  5850		wcd->regmap = data->regmap;
  5851		wcd->extclk = data->extclk;
  5852		wcd->sdev = to_slim_device(data->dev);
  5853		mutex_init(&wcd->sysclk_mutex);
  5854		mutex_init(&wcd->micb_lock);
  5855		wcd->common.dev = dev->parent;
  5856		wcd->common.max_bias = 4;
  5857	
  5858		ret = wcd934x_codec_parse_data(wcd);
  5859		if (ret)
  5860			return ret;
  5861	
> 5862		ret = devm_add_action_or_reset(dev, (void (*)(void *))put_device, &wcd->sidev->dev);
  5863		if (ret)
  5864			return ret;
  5865	
  5866		/* set default rate 9P6MHz */
  5867		regmap_update_bits(wcd->regmap, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
  5868				   WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK,
  5869				   WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ);
  5870		memcpy(wcd->rx_chs, wcd934x_rx_chs, sizeof(wcd934x_rx_chs));
  5871		memcpy(wcd->tx_chs, wcd934x_tx_chs, sizeof(wcd934x_tx_chs));
  5872	
  5873		irq = regmap_irq_get_virq(data->irq_data, WCD934X_IRQ_SLIMBUS);
  5874		if (irq < 0)
  5875			return dev_err_probe(wcd->dev, irq, "Failed to get SLIM IRQ\n");
  5876	
  5877		ret = devm_request_threaded_irq(dev, irq, NULL,
  5878						wcd934x_slim_irq_handler,
  5879						IRQF_TRIGGER_RISING | IRQF_ONESHOT,
  5880						"slim", wcd);
  5881		if (ret)
  5882			return dev_err_probe(dev, ret, "Failed to request slimbus irq\n");
  5883	
  5884		wcd934x_register_mclk_output(wcd);
  5885		platform_set_drvdata(pdev, wcd);
  5886	
  5887		return devm_snd_soc_register_component(dev, &wcd934x_component_drv,
  5888						       wcd934x_slim_dais,
  5889						       ARRAY_SIZE(wcd934x_slim_dais));
  5890	}
  5891	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki