RE: [PATCH v13 2/2] leds: ltc3220: Add Support for LTC3220 18 channel LED Driver

"Escala, Edelweise" <[email protected]>
Newsgroups org.kernel.vger.linux-leds,dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-devicetree
Message-ID <DS0PR03MB7228EFE517CF37673FDE686AEDFE2@DS0PR03MB7228.namprd03.prod.outlook.com>
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to
> consider:
> - [High] Aggregated LED mode breaks after suspend/resume because
> regcache_sync() overwrites LEDs 2-18 with zeros.
> - [Medium] Missing LED_CORE_SUSPENDRESUME flag and missing locking in
> suspend/resume handlers allow race conditions.
> --
> 
> --- Patch [2]: [PATCH v13 2/2] leds: ltc3220: Add Support for LTC3220 18 channel
> LED Driver --- commit 530249002ce164e8156c89d4dcd1994b3713c0c8
> Author: Edelweise Escala <[email protected]>
> 
> 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
> > --- /dev/null
> > +++ b/drivers/leds/leds-ltc3220.c
> 
> [ ... ]
> 
> > @@ -371,20 +371,11 @@ static int ltc3220_suspend(struct device *dev)
> > {
> >  	struct ltc3220 *ltc3220 = i2c_get_clientdata(to_i2c_client(dev));
> >  	int ret;
> >
> 
> [Severity: Medium]
> Should ltc3220->lock be held here?
> 
> Because LED_CORE_SUSPENDRESUME is not set on the led_classdev, triggers
> and sysfs writes can still fire during suspend, potentially racing with these state
> changes and executing I2C writes while the device is in shutdown.
> 
> >  	ret = regmap_update_bits(ltc3220->regmap, LTC3220_COMMAND_REG,
> >  				 LTC3220_SHUTDOWN_MASK,
> LTC3220_SHUTDOWN_MASK);
> >  	if (ret)
> >  		return ret;
> 
> [ ... ]

This is already handled correctly. The resume function:
1. Reads COMMAND_REG to detect if QUICK_WRITE is enabled
2. Temporarily disables QUICK_WRITE before regcache_sync()
3. Performs regcache_sync() with QUICK_WRITE disabled
4. Re-enables QUICK_WRITE after sync completes

With QUICK_WRITE disabled during regcache_sync(), writes to LEDs 2-18 apply 
only to those specific channels, not broadcast to all. The cached zeros correctly 
restore each LED's individual off state. When QUICK_WRITE is re-enabled afterward, 
subsequent brightness writes work correctly.


> 
> > @@ -391,24 +382,15 @@ static int ltc3220_resume(struct device *dev)  {
> >  	struct ltc3220 *ltc3220 = i2c_get_clientdata(to_i2c_client(dev));
> >  	bool quick_write_enabled;
> >  	unsigned int command_reg;
> >  	int ret;
> 
> [ ... ]
> 
> >  	if (quick_write_enabled) {
> >  		ret = regmap_update_bits(ltc3220->regmap,
> LTC3220_COMMAND_REG,
> >  					 LTC3220_QUICK_WRITE_MASK, 0);
> >  		if (ret)
> >  			return ret;
> >  	}
> >
> >  	ret = regmap_update_bits(ltc3220->regmap, LTC3220_COMMAND_REG,
> >  				 LTC3220_SHUTDOWN_MASK, 0);
> >  	if (ret)
> >  		return ret;
> >
> >  	usleep_range(10000, 12000);
> >
> 
> [Severity: Medium]
> Because the driver does not set LED_CORE_SUSPENDRESUME or hold ltc3220-
> >lock during resume, can an LED trigger fire during this sleep?
> 
> If a trigger calls ltc3220_set_led_data() here while QUICK_WRITE is temporarily
> disabled, the write would only apply to a single LED instead of broadcasting to all
> channels.
> 
> >  	ret = regcache_sync(ltc3220->regmap);
> 
> [Severity: High]
> Does this regcache_sync() break aggregated LED mode?
> 
> Since the cache for LEDs 2-18 contains zeros from their initial state, and
> QUICK_WRITE is disabled during the sync, this looks like it will explicitly write
> zeros to those channels, leaving most LEDs permanently off after resume.
> 
> >  	if (ret)
> >  		return ret;
> 
> [ ... ]
> 
> > @@ -499,19 +481,10 @@ static int ltc3220_probe(struct i2c_client
> > *client)
> 
> [ ... ]
> 
> >  	/* 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;
> 
> [ ... ]
> 
> >  		init_data.fwnode = child;
> >  		init_data.devicename = "ltc3220";
> >
> >  		led_index = source - 1;
> >  		led = &ltc3220->uled_cfg[led_index];
> >
> 
> [Severity: Medium]
> Does this led_cdev need the LED_CORE_SUSPENDRESUME flag set in its flags
> field so the LED core knows to suspend triggers during system suspend?
> 

The driver intentionally omits LED_CORE_SUSPENDRESUME because:
1. Hardware power management is handled via the SHUTDOWN bit
2. The LED core's forced brightness-to-zero on suspend would interfere with 
   hardware blink/gradation state restoration


> >  		ret = devm_led_classdev_register_ext(&client->dev, &led-
> >led_cdev, &init_data);
> >  		if (ret)
> >  			return dev_err_probe(&client->dev, ret, "Failed to
> register LED class\n");
> >  	}
> >
> >  	return 0;
> >  }
> 
> --
> Sashiko AI review ·
> https://urldefense.com/v3/__https://sashiko.dev/*/patchset/20260709-ltc3220-
> driver-v13-0-
> [email protected]?part=2__;Iw!!A3Ni8CS0y2Y!5sRuO2kidckEwZZPnnr
> M2kxEPjgElsbpjq_JYWKopaoBxsxjSoGN4OBNJg9BlPKQcBKNHsRD1Lmz-
> 9bG73HqJXnacOE$
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.