Skip to content

Commit ffbf1fc

Browse files
javiercarrascocruzlag-linaro
authored andcommitted
leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()
The current implementation accesses the `child` fwnode handle outside of fwnode_for_each_available_child_node() without incrementing its refcount. Add the missing call to `fwnode_handle_get(child)`. The cleanup process where `child` is accessed is not right either because a single call to `fwnode_handle_put()` is carried out in case of an error, ignoring unasigned nodes at the point when the error happens. Keep `child` inside of the first loop, and use the helper pointer that receives references via `fwnode_handle_get()` to handle the child nodes within the second loop. Moreover, the iterated nodes are direct children of the device node, and the `device_for_each_child_node()` macro accounts for child node availability. By restricting `child` to live within that loop, the scoped version of it can be used to simplify the error handling. `fwnode_for_each_available_child_node()` is meant to access the child nodes of an fwnode, and therefore not direct child nodes of the device node. Use `device_for_each_child_node_scoped()` to indicate device's direct child nodes. Fixes: 8325642 ("leds: bd2606mvv: Driver for the Rohm 6 Channel i2c LED driver") Signed-off-by: Javier Carrasco <[email protected]> Link: https://lore.kernel.org/r/20240721-device_for_each_child_node-available-v2-3-f33748fd8b2d@gmail.com Signed-off-by: Lee Jones <[email protected]>
1 parent 29357f8 commit ffbf1fc

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

drivers/leds/leds-bd2606mvv.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,14 @@ static const struct regmap_config bd2606mvv_regmap = {
6969

7070
static int bd2606mvv_probe(struct i2c_client *client)
7171
{
72-
struct fwnode_handle *np, *child;
7372
struct device *dev = &client->dev;
7473
struct bd2606mvv_priv *priv;
7574
struct fwnode_handle *led_fwnodes[BD2606_MAX_LEDS] = { 0 };
7675
int active_pairs[BD2606_MAX_LEDS / 2] = { 0 };
7776
int err, reg;
78-
int i;
77+
int i, j;
7978

80-
np = dev_fwnode(dev);
81-
if (!np)
79+
if (!dev_fwnode(dev))
8280
return -ENODEV;
8381

8482
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -94,20 +92,18 @@ static int bd2606mvv_probe(struct i2c_client *client)
9492

9593
i2c_set_clientdata(client, priv);
9694

97-
fwnode_for_each_available_child_node(np, child) {
95+
device_for_each_child_node_scoped(dev, child) {
9896
struct bd2606mvv_led *led;
9997

10098
err = fwnode_property_read_u32(child, "reg", &reg);
101-
if (err) {
102-
fwnode_handle_put(child);
99+
if (err)
103100
return err;
104-
}
105-
if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg]) {
106-
fwnode_handle_put(child);
101+
102+
if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg])
107103
return -EINVAL;
108-
}
104+
109105
led = &priv->leds[reg];
110-
led_fwnodes[reg] = child;
106+
led_fwnodes[reg] = fwnode_handle_get(child);
111107
active_pairs[reg / 2]++;
112108
led->priv = priv;
113109
led->led_no = reg;
@@ -130,7 +126,8 @@ static int bd2606mvv_probe(struct i2c_client *client)
130126
&priv->leds[i].ldev,
131127
&init_data);
132128
if (err < 0) {
133-
fwnode_handle_put(child);
129+
for (j = i; j < BD2606_MAX_LEDS; j++)
130+
fwnode_handle_put(led_fwnodes[j]);
134131
return dev_err_probe(dev, err,
135132
"couldn't register LED %s\n",
136133
priv->leds[i].ldev.name);

0 commit comments

Comments
 (0)