Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: rgb: leds-qcom-lpg: Fix calculation of best period Hi-Res PWMs

When determining the actual best period by looping through all
possible PWM configs, the resolution currently used is based on
bit shift value which is off-by-one above the possible maximum
PWM value allowed.

So subtract one from the resolution before determining the best
period so that the maximum duty cycle requested by the PWM user
won't result in a value above the maximum allowed by the selected
resolution.

Cc: stable@vger.kernel.org # 6.4
Fixes: b00d2ed37617 ("leds: rgb: leds-qcom-lpg: Add support for high resolution PWM")
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Link: https://lore.kernel.org/r/20250305-leds-qcom-lpg-fix-max-pwm-on-hi-res-v4-3-bfe124a53a9f@linaro.org
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Abel Vesa and committed by
Lee Jones
2528eec7 b7881eac

+3 -3
+3 -3
drivers/leds/rgb/leds-qcom-lpg.c
··· 462 462 max_res = LPG_RESOLUTION_9BIT; 463 463 } 464 464 465 - min_period = div64_u64((u64)NSEC_PER_SEC * (1 << pwm_resolution_arr[0]), 465 + min_period = div64_u64((u64)NSEC_PER_SEC * ((1 << pwm_resolution_arr[0]) - 1), 466 466 clk_rate_arr[clk_len - 1]); 467 467 if (period <= min_period) 468 468 return -EINVAL; ··· 483 483 */ 484 484 485 485 for (i = 0; i < pwm_resolution_count; i++) { 486 - resolution = 1 << pwm_resolution_arr[i]; 486 + resolution = (1 << pwm_resolution_arr[i]) - 1; 487 487 for (clk_sel = 1; clk_sel < clk_len; clk_sel++) { 488 488 u64 numerator = period * clk_rate_arr[clk_sel]; 489 489 ··· 1292 1292 if (ret) 1293 1293 return ret; 1294 1294 1295 - state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * (1 << resolution) * 1295 + state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * ((1 << resolution) - 1) * 1296 1296 pre_div * (1 << m), refclk); 1297 1297 state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk); 1298 1298 } else {