In exynos_get_pmu_regmap_by_phandle(), driver_find_device_by_of_node() utilizes driver_find_device_by_fwnode() which internally calls driver_find_device() to locate the matching device. driver_find_device() increments the reference count of the found device by calling get_device(), but exynos_get_pmu_regmap_by_phandle() fails to call put_device() to decrement the reference count before returning. This results in a reference count leak of the device each time exynos_get_pmu_regmap_by_phandle() is executed, which may prevent the device from being properly released and cause a memory leak.
Since Exynos-PMU is a core system device that is not unloaded at runtime, and regmap is created during device probing, releasing the temporary device reference does not affect the validity of regmap. From the perspective of code standards and maintainability, reference count leakage is a genuine code defect that should be fixed. Even if the leakage does not immediately cause issues in certain scenarios, known leakage points should not be left unaddressed.
Found by code review.
Cc: stable@vger.kernel.org Fixes: 0b7c6075022c ("soc: samsung: exynos-pmu: Add regmap support for SoCs that protect PMU regs") Signed-off-by: Ma Ke make24@iscas.ac.cn --- Changes in v2: - modified the typo of the variable in the patch. Sorry for the typo; - added more detailed description. --- drivers/soc/samsung/exynos-pmu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index a77288f49d24..b80cc30c1100 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -302,6 +302,7 @@ struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np, { struct device_node *pmu_np; struct device *dev; + struct regmap *regmap;
if (propname) pmu_np = of_parse_phandle(np, propname, 0); @@ -325,7 +326,10 @@ struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np, if (!dev) return ERR_PTR(-EPROBE_DEFER);
- return syscon_node_to_regmap(pmu_np); + regmap = syscon_node_to_regmap(pmu_np); + put_device(dev); + + return regmap; } EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);