From: Maurice Hieronymus Date: Fri, 5 Jun 2026 07:03:59 +0000 (+0200) Subject: pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f9b73071c15001530e6697491b6db1bf639f4c7;p=thirdparty%2Fkernel%2Flinux.git pwm: th1520: Remove requirement for mul_u64_u64_div_u64_roundup The cycle register is always u32, so cycles_to_ns() can take a u32 instead of a u64. With that narrowing, cycles * NSEC_PER_SEC is at most u32::MAX * 1e9 (~4.3e18), which fits in u64 without overflow. The saturating arithmetic is therefore no longer needed, and the ceiling division can use Rust's u64::div_ceil() directly instead of the open-coded numerator/denominator form. This also drops the TODO referring to a future mul_u64_u64_div_u64_roundup kernel helper, which is no longer required. Reviewed-by: Michal Wilczynski Signed-off-by: Maurice Hieronymus Link: https://patch.msgid.link/20260605-pwm-th1520-fix-v2-1-5921e3a595f7@mailbox.org Signed-off-by: Uwe Kleine-König --- diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs index ddd44a5ce4979..933c1ec59c2a4 100644 --- a/drivers/pwm/pwm_th1520.rs +++ b/drivers/pwm/pwm_th1520.rs @@ -67,16 +67,10 @@ fn ns_to_cycles(ns: u64, rate_hz: u64) -> u64 { ns.saturating_mul(rate_hz) / NSEC_PER_SEC_U64 } -fn cycles_to_ns(cycles: u64, rate_hz: u64) -> u64 { +fn cycles_to_ns(cycles: u32, rate_hz: u64) -> u64 { const NSEC_PER_SEC_U64: u64 = time::NSEC_PER_SEC as u64; - // TODO: Replace with a kernel helper like `mul_u64_u64_div_u64_roundup` - // once available in Rust. - let numerator = cycles - .saturating_mul(NSEC_PER_SEC_U64) - .saturating_add(rate_hz - 1); - - numerator / rate_hz + (u64::from(cycles) * NSEC_PER_SEC_U64).div_ceil(rate_hz) } /// Hardware-specific waveform representation for TH1520. @@ -192,15 +186,15 @@ impl pwm::PwmOps for Th1520PwmDriverData { return Ok(()); } - wf.period_length_ns = cycles_to_ns(u64::from(wfhw.period_cycles), rate_hz); + wf.period_length_ns = cycles_to_ns(wfhw.period_cycles, rate_hz); - let duty_cycles = u64::from(wfhw.duty_cycles); + let duty_cycles = wfhw.duty_cycles; if (wfhw.ctrl_val & TH1520_PWM_FPOUT) != 0 { wf.duty_length_ns = cycles_to_ns(duty_cycles, rate_hz); wf.duty_offset_ns = 0; } else { - let period_cycles = u64::from(wfhw.period_cycles); + let period_cycles = wfhw.period_cycles; let original_duty_cycles = period_cycles.saturating_sub(duty_cycles); // For an inverted signal, `duty_length_ns` is the high time (period - low_time).