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

mfd: exynos-lpass: Fix another error handling path in exynos_lpass_probe()

If devm_of_platform_populate() fails, some clean-up needs to be done, as
already done in the remove function.

Add a new devm_add_action_or_reset() to fix the leak in the probe and
remove the need of a remove function.

Fixes: c695abab2429 ("mfd: Add Samsung Exynos Low Power Audio Subsystem driver")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/69471e839efc0249a504492a8de3497fcdb6a009.1745247209.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Christophe JAILLET and committed by
Lee Jones
f41cc37f b70b8455

+15 -10
+15 -10
drivers/mfd/exynos-lpass.c
··· 104 104 .fast_io = true, 105 105 }; 106 106 107 + static void exynos_lpass_disable_lpass(void *data) 108 + { 109 + struct platform_device *pdev = data; 110 + struct exynos_lpass *lpass = platform_get_drvdata(pdev); 111 + 112 + pm_runtime_disable(&pdev->dev); 113 + if (!pm_runtime_status_suspended(&pdev->dev)) 114 + exynos_lpass_disable(lpass); 115 + } 116 + 107 117 static int exynos_lpass_probe(struct platform_device *pdev) 108 118 { 109 119 struct device *dev = &pdev->dev; 110 120 struct exynos_lpass *lpass; 111 121 void __iomem *base_top; 122 + int ret; 112 123 113 124 lpass = devm_kzalloc(dev, sizeof(*lpass), GFP_KERNEL); 114 125 if (!lpass) ··· 145 134 pm_runtime_enable(dev); 146 135 exynos_lpass_enable(lpass); 147 136 137 + ret = devm_add_action_or_reset(dev, exynos_lpass_disable_lpass, pdev); 138 + if (ret) 139 + return ret; 140 + 148 141 return devm_of_platform_populate(dev); 149 - } 150 - 151 - static void exynos_lpass_remove(struct platform_device *pdev) 152 - { 153 - struct exynos_lpass *lpass = platform_get_drvdata(pdev); 154 - 155 - pm_runtime_disable(&pdev->dev); 156 - if (!pm_runtime_status_suspended(&pdev->dev)) 157 - exynos_lpass_disable(lpass); 158 142 } 159 143 160 144 static int __maybe_unused exynos_lpass_suspend(struct device *dev) ··· 189 183 .of_match_table = exynos_lpass_of_match, 190 184 }, 191 185 .probe = exynos_lpass_probe, 192 - .remove = exynos_lpass_remove, 193 186 }; 194 187 module_platform_driver(exynos_lpass_driver); 195 188