From: sashiko-bot@kernel.org
To: "Edelweise Escala" <edelweise.escala@analog.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v10 2/2] leds: ltc3220: Add Support for LTC3220 18 channel LED Driver
Date: Mon, 15 Jun 2026 05:38:03 +0000 [thread overview]
Message-ID: <20260615053804.0B02E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260615-ltc3220-driver-v10-2-916562c88598@analog.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Duplicate LED `reg` values bypass the validation check, leading to a doubly-linked list corruption in the LED core.
- [Medium] Missing LED class suspend/resume calls in system PM callbacks.
- [Medium] The `pattern_set` callback silently ignores the `repeat` parameter, breaking continuous patterns.
- [Low] Setting blink mode on a deactivated LED causes an unnecessary I2C read and hardware glitch.
--
commit ff936b952a6a427e0232229537a10438e4f34a11
Author: Edelweise Escala <edelweise.escala@analog.com>
Subject: leds: ltc3220: Add Support for LTC3220 18 channel LED Driver
Add driver for the LTC3220 18-channel LED driver with I2C interface,
individual brightness control, and hardware-assisted blink/gradation features.
> diff --git a/drivers/leds/leds-ltc3220.c b/drivers/leds/leds-ltc3220.c
> new file mode 100644
> index 0000000000000..f95174ae451ba
> --- /dev/null
> +++ b/drivers/leds/leds-ltc3220.c
[ ... ]
> +static int ltc3220_pattern_set(struct led_classdev *led_cdev,
> + struct led_pattern *pattern,
> + u32 len, int repeat)
> +{
[Severity: Medium]
Does this callback silently ignore the repeat parameter?
If the user requests infinite repetition (for example, repeat is -1), the
driver returns 0 without programming continuous breathing. Should this return
-EOPNOTSUPP when repetition is requested, so the LED core can fall back to
software-driven repetition instead of halting after a single ramp?
> + struct ltc3220_uled_cfg *uled_cfg = container_of(led_cdev, struct ltc3220_uled_cfg,
> + led_cdev);
[ ... ]
> +static int ltc3220_blink_set(struct led_classdev *led_cdev,
> + unsigned long *delay_on,
> + unsigned long *delay_off)
> +{
[ ... ]
> + /* Ensure LED has non-zero brightness before enabling blink mode */
> + if (uled_cfg->reg_value == 0) {
> + ret = regmap_write(ltc3220->regmap, LTC3220_ULED_REG(uled_cfg->led_index),
> + led_cdev->max_brightness);
> + if (ret)
> + return ret;
> +
> + uled_cfg->reg_value = led_cdev->max_brightness;
> + }
> +
> + return regmap_update_bits(ltc3220->regmap, LTC3220_ULED_REG(uled_cfg->led_index),
> + LTC3220_LED_MODE_MASK,
> + FIELD_PREP(LTC3220_LED_MODE_MASK, LTC3220_BLINK_MODE));
> +}
[Severity: Low]
When ltc3220_blink_set() is called on an LED with zero brightness, does this
sequence cause a visual glitch and an unnecessary I2C read?
The first regmap_write() turns the LED on solid in normal mode, and then
regmap_update_bits() incurs an I2C read to switch it to blink mode. Could
the driver construct the final 8-bit value from the cached brightness and
write it directly using a single regmap_write()?
[ ... ]
> +static int ltc3220_suspend(struct device *dev)
> +{
> + struct ltc3220 *ltc3220 = i2c_get_clientdata(to_i2c_client(dev));
> +
> + return regmap_update_bits(ltc3220->regmap, LTC3220_COMMAND_REG,
> + LTC3220_SHUTDOWN_MASK, LTC3220_SHUTDOWN_MASK);
> +}
[Severity: Medium]
Does this suspend callback miss notifying the LED core about the suspension?
By not iterating over the registered LEDs and calling led_classdev_suspend(),
the LED core remains unaware the device is suspended and will not pause
triggers. Could an active software trigger attempt an I2C transaction while
the system is suspending, potentially causing bus timeouts?
[ ... ]
> +static int ltc3220_probe(struct i2c_client *client)
> +{
[ ... ]
> + /* First pass: validate configuration and set up LED structures */
> + device_for_each_child_node_scoped(&client->dev, child) {
> + struct ltc3220_uled_cfg *led;
> + u32 source;
[ ... ]
> + /* LED node reg/index/address goes from 1 to 18 */
> + led_index = source - 1;
> + led = <c3220->uled_cfg[led_index];
> +
> + if (led->led_cdev.dev)
> + return dev_err_probe(&client->dev, -EINVAL,
> + "Duplicate LED reg %u found", source);
[Severity: High]
Is led_cdev.dev always null during the first pass of ltc3220_probe()?
Since ltc3220 is allocated with devm_kzalloc(), led_cdev.dev will be zero. It
is only assigned during devm_led_classdev_register_ext() in the second pass,
so this duplicate checking logic appears to be bypassed.
If a device tree contains duplicate reg values, will it silently overwrite
the same uled_cfg structure during this first pass?
[ ... ]
> + /* Second pass: register LEDs after validation */
> + device_for_each_child_node_scoped(&client->dev, child) {
> + struct led_init_data init_data = {};
> + struct ltc3220_uled_cfg *led;
> + u32 source;
> +
> + ret = fwnode_property_read_u32(child, "reg", &source);
> + if (ret)
> + return ret;
> +
> + init_data.fwnode = child;
> + init_data.devicename = "ltc3220";
> +
> + led_index = source - 1;
> + led = <c3220->uled_cfg[led_index];
> +
> + ret = devm_led_classdev_register_ext(&client->dev, &led->led_cdev, &init_data);
[Severity: High]
Following from the duplicate check bypass above, if a duplicate reg value is
present, will devm_led_classdev_register_ext() call list_add_tail() twice on
the exact same node address? This would corrupt the LED core's doubly-linked
list and reliably cause a kernel panic upon iteration or removal.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615-ltc3220-driver-v10-0-916562c88598@analog.com?part=2
next prev parent reply other threads:[~2026-06-15 5:38 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-15 5:26 [PATCH v10 0/2] Add Support for LTC3220 18 Channel LED Driver Edelweise Escala
2026-06-15 5:26 ` [PATCH v10 1/2] dt-bindings: leds: Add LTC3220 18 channel " Edelweise Escala
2026-06-15 5:26 ` [PATCH v10 2/2] leds: ltc3220: Add Support for " Edelweise Escala
2026-06-15 5:38 ` sashiko-bot [this message]
2026-06-15 5:52 ` Escala, Edelweise
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260615053804.0B02E1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=edelweise.escala@analog.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox