[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240721-device_for_each_child_node-available-v2-3-f33748fd8b2d@gmail.com>
Date: Sun, 21 Jul 2024 17:19:03 +0200
From: Javier Carrasco <javier.carrasco.cruz@...il.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
"Rafael J. Wysocki" <rafael@...nel.org>,
Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
Jonathan Cameron <jic23@...nel.org>, Rob Herring <robh@...nel.org>,
Daniel Scally <djrscally@...il.com>,
Heikki Krogerus <heikki.krogerus@...ux.intel.com>,
Sakari Ailus <sakari.ailus@...ux.intel.com>,
Jean Delvare <jdelvare@...e.com>, Guenter Roeck <linux@...ck-us.net>,
Pavel Machek <pavel@....cz>, Lee Jones <lee@...nel.org>,
Marcin Wojtas <marcin.s.wojtas@...il.com>,
Russell King <linux@...linux.org.uk>,
"David S. Miller" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>,
Andreas Kemnade <andreas@...nade.info>
Cc: linux-acpi@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-hwmon@...r.kernel.org, linux-leds@...r.kernel.org,
netdev@...r.kernel.org, Javier Carrasco <javier.carrasco.cruz@...il.com>
Subject: [PATCH v2 3/6] 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: 8325642d2757 ("leds: bd2606mvv: Driver for the Rohm 6 Channel i2c LED driver")
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@...il.com>
---
drivers/leds/leds-bd2606mvv.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/leds/leds-bd2606mvv.c b/drivers/leds/leds-bd2606mvv.c
index 3fda712d2f80..c1181a35d0f7 100644
--- a/drivers/leds/leds-bd2606mvv.c
+++ b/drivers/leds/leds-bd2606mvv.c
@@ -69,16 +69,14 @@ static const struct regmap_config bd2606mvv_regmap = {
static int bd2606mvv_probe(struct i2c_client *client)
{
- struct fwnode_handle *np, *child;
struct device *dev = &client->dev;
struct bd2606mvv_priv *priv;
struct fwnode_handle *led_fwnodes[BD2606_MAX_LEDS] = { 0 };
int active_pairs[BD2606_MAX_LEDS / 2] = { 0 };
int err, reg;
- int i;
+ int i, j;
- np = dev_fwnode(dev);
- if (!np)
+ if (!dev_fwnode(dev))
return -ENODEV;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -94,20 +92,18 @@ static int bd2606mvv_probe(struct i2c_client *client)
i2c_set_clientdata(client, priv);
- fwnode_for_each_available_child_node(np, child) {
+ device_for_each_child_node_scoped(dev, child) {
struct bd2606mvv_led *led;
err = fwnode_property_read_u32(child, "reg", ®);
- if (err) {
- fwnode_handle_put(child);
+ if (err)
return err;
- }
- if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg]) {
- fwnode_handle_put(child);
+
+ if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg])
return -EINVAL;
- }
+
led = &priv->leds[reg];
- led_fwnodes[reg] = child;
+ led_fwnodes[reg] = fwnode_handle_get(child);
active_pairs[reg / 2]++;
led->priv = priv;
led->led_no = reg;
@@ -130,7 +126,8 @@ static int bd2606mvv_probe(struct i2c_client *client)
&priv->leds[i].ldev,
&init_data);
if (err < 0) {
- fwnode_handle_put(child);
+ for (j = i; j < BD2606_MAX_LEDS; j++)
+ fwnode_handle_put(led_fwnodes[j]);
return dev_err_probe(dev, err,
"couldn't register LED %s\n",
priv->leds[i].ldev.name);
--
2.43.0
Powered by blists - more mailing lists