Patch "leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()" has been added to the 6.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()

to the 6.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     leds-bd2606mvv-fix-device-child-node-usage-in-bd2606.patch
and it can be found in the queue-6.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 9ded405f86e8237e4e28c20248244230371dc593
Author: Javier Carrasco <javier.carrasco.cruz@xxxxxxxxx>
Date:   Sun Jul 21 17:19:03 2024 +0200

    leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()
    
    [ Upstream commit ffbf1fcb421429916a861cfc25dfe0c6387dda75 ]
    
    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@xxxxxxxxx>
    Link: https://lore.kernel.org/r/20240721-device_for_each_child_node-available-v2-3-f33748fd8b2d@xxxxxxxxx
    Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/leds/leds-bd2606mvv.c b/drivers/leds/leds-bd2606mvv.c
index 3fda712d2f809..c1181a35d0f76 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", &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);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux