regulator: tps6594: Fix device node reference leaks in multiphase loop

In tps6594_regulator_probe(), the multi-phase configuration loop calls
of_find_node_by_name() to find buck nodes by name, and of_get_parent()
twice to navigate to the PMIC parent node. None of the acquired node
references (np, intermediate parent, np_pmic_parent) are ever released
via of_node_put(), causing a reference leak on every loop iteration.

Additionally, of_find_node_by_name() can return NULL, but the result was
immediately passed to of_node_full_name() and of_get_parent() without a
NULL check, which could lead to a NULL pointer dereference.

Fix this by:
- Adding a NULL check for np after of_find_node_by_name()
- Storing the intermediate parent node in a local variable np_parent
- Calling of_node_put() on np, np_parent and np_pmic_parent at the
  end of each loop iteration

Fixes: f17ccc5deb ("regulator: tps6594-regulator: Add driver for TI TPS6594 regulators")
Signed-off-by: Uday Khare <udaykhare77@gmail.com>
Link: https://patch.msgid.link/20260618132327.11529-1-udaykhare77@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Uday Khare 2026-06-18 18:53:27 +05:30 committed by Mark Brown
parent a36cc103a6
commit 7fd28093b3
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -669,13 +669,20 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
* buck_configured to avoid creating bucks for every buck in multiphase
*/
for (multi = 0; multi < desc->num_multi_phase_regs; multi++) {
struct device_node *np_parent;
multi_regs = &desc->multi_phase_regs[multi];
np = of_find_node_by_name(tps->dev->of_node, multi_regs->supply_name);
npname = of_node_full_name(np);
np_pmic_parent = of_get_parent(of_get_parent(np));
if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))
if (!np)
continue;
if (strcmp(npname, multi_regs->supply_name) == 0) {
npname = of_node_full_name(np);
np_parent = of_get_parent(np);
np_pmic_parent = of_get_parent(np_parent);
if (np_pmic_parent &&
!of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name) &&
strcmp(npname, multi_regs->supply_name) == 0) {
switch (multi) {
case MULTI_BUCK12:
buck_multi[0] = true;
@ -706,6 +713,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
break;
}
}
of_node_put(np_pmic_parent);
of_node_put(np_parent);
of_node_put(np);
}
reg_irq_nb = desc->num_irq_types * (desc->num_buck_regs + desc->num_ldo_regs);