From: Johan Adolfsson johan.adolfsson@axis.com
[ Upstream commit 2e84a5e5374232e6f356ce5c079a5658d7e4af2c ]
mc_subled used for multi_index needs well defined array indexes, to guarantee the desired result, use reg for that.
If devicetree child nodes is processed in random or reverse order you may end up with multi_index "blue green red" instead of the expected "red green blue". If user space apps uses multi_index to deduce how to control the leds they would most likely be broken without this patch if devicetree processing is reversed (which it appears to be).
arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-fuji.dts has reg set but I don't see how it can have worked without this change.
If reg is not set, an error is returned, If reg is out of range, an error is returned. reg within led child nodes starts with 0, to map to the iout in each bank.
Signed-off-by: Johan Adolfsson johan.adolfsson@axis.com Reviewed-by: Jacek Anaszewski jacek.anaszewski@gmail.com Link: https://lore.kernel.org/r/20250617-led-fix-v7-1-cdbe8efc88fa@axis.com Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
**Backport Status: YES**
This commit is a clear candidate for backporting to stable kernel trees. Here's my extensive analysis:
## Bug Fix Nature
The commit fixes a **real bug** where LED ordering could be incorrect when device tree child nodes are processed in random or reverse order. Looking at the code changes:
1. **Before the fix** (line 487 in original): ```c mc_led_info[num_colors].color_index = color_id; ``` The code was using `num_colors` as the array index, which simply increments for each LED found, regardless of the intended order.
2. **After the fix**: ```c mc_led_info[multi_index].color_index = color_id; ``` The code now correctly uses the `reg` property value as the index, ensuring deterministic LED ordering.
## Impact on Users
This bug has **significant user-visible impact**: - User space applications relying on `multi_index` to control LEDs would break if device tree processing order changes - The commit message explicitly states: "If user space apps uses multi_index to deduce how to control the leds they would most likely be broken" - Could result in "blue green red" ordering instead of expected "red green blue"
## Fix Characteristics
The fix meets stable tree criteria: 1. **Small and contained**: Only ~13 lines of actual logic change 2. **No new features**: Simply ensures correct array indexing 3. **Low regression risk**: Adds proper validation (bounds checking for `multi_index`) 4. **Clear bug fix**: Not a refactoring or optimization
## Additional Safety
The patch adds important safety checks: - Requires `reg` property to be set (returns -EINVAL if missing) - Validates `reg` is within bounds (`< LP50XX_LEDS_PER_MODULE` which is 3) - These checks prevent array out-of-bounds access
## Real-world Impact
The commit message mentions that `arch/arm/boot/dts/aspeed/aspeed-bmc- facebook-fuji.dts` has reg set but wouldn't work correctly without this fix, indicating this affects real hardware in production.
## Stable Tree Rules Compliance
This fix adheres to stable kernel rules: - Fixes a real bug affecting users - Minimal change with clear boundaries - No architectural changes - Confined to a single driver subsystem (leds-lp50xx) - Adds necessary error checking that was missing
The bug could cause unpredictable LED behavior depending on device tree parsing order, which is exactly the type of issue stable kernels should address.
drivers/leds/leds-lp50xx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index 02cb1565a9fb..94f8ef6b482c 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -476,6 +476,7 @@ static int lp50xx_probe_dt(struct lp50xx *priv) return -ENOMEM;
fwnode_for_each_child_node(child, led_node) { + int multi_index; ret = fwnode_property_read_u32(led_node, "color", &color_id); if (ret) { @@ -483,8 +484,16 @@ static int lp50xx_probe_dt(struct lp50xx *priv) dev_err(priv->dev, "Cannot read color\n"); return ret; } + ret = fwnode_property_read_u32(led_node, "reg", &multi_index); + if (ret != 0) { + dev_err(priv->dev, "reg must be set\n"); + return -EINVAL; + } else if (multi_index >= LP50XX_LEDS_PER_MODULE) { + dev_err(priv->dev, "reg %i out of range\n", multi_index); + return -EINVAL; + }
- mc_led_info[num_colors].color_index = color_id; + mc_led_info[multi_index].color_index = color_id; num_colors++; }