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,
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-... 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@i...) 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@i...)
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
linux-stable-mirror@lists.linaro.org