[PATCH 01/10] leds: rgb: ktd202x: Fix the flash period of short blinks on 32 bit

From: Joseph Telaak via B4 Relay

Date: Sun Nov 01 2026 - 21:15:51 EST


From: Joseph Telaak <joseph@xxxxxxxxxx>

When delay_on + delay_off is below 256 ms, the unsigned subtraction of
KTD202X_FLASH_PERIOD_MIN_MS wraps. On 64 bit the result truncates to -1
or -2 and gets clamped to the shortest period, but on 32 bit it
truncates to 33554431 or 33554430 and gets clamped to the longest one,
so asking for a fast blink gives a blink every 16 seconds.

Compare before subtracting.

Fixes: 0ebdb7210943 ("leds: Add ktd202x driver")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Joseph Telaak <joseph@xxxxxxxxxx>
---
drivers/leds/rgb/leds-ktd202x.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/leds/rgb/leds-ktd202x.c b/drivers/leds/rgb/leds-ktd202x.c
index 143020945..539cf425c 100644
--- a/drivers/leds/rgb/leds-ktd202x.c
+++ b/drivers/leds/rgb/leds-ktd202x.c
@@ -296,9 +296,13 @@ static int ktd202x_blink_set(struct ktd202x_led *led, unsigned long *delay_on,
/* Convert into values the HW will understand. */

/* Integer representation of time of flash period */
- num_steps = (*delay_on + *delay_off - KTD202X_FLASH_PERIOD_MIN_MS) /
- KTD202X_FLASH_PERIOD_STEP_MS;
- num_steps = clamp(num_steps, 0, KTD202X_FLASH_PERIOD_MAX_STEPS);
+ delay_total_ms = *delay_on + *delay_off;
+ if (delay_total_ms < KTD202X_FLASH_PERIOD_MIN_MS)
+ num_steps = 0;
+ else
+ num_steps = min_t(unsigned long, KTD202X_FLASH_PERIOD_MAX_STEPS,
+ (delay_total_ms - KTD202X_FLASH_PERIOD_MIN_MS) /
+ KTD202X_FLASH_PERIOD_STEP_MS);

/* Integer representation of percentage of LED ON time */
on = (*delay_on * KTD202X_FLASH_ON_MAX) / (*delay_on + *delay_off);

--
Git-155)