[PATCH 5/5] clk: qcom: clk-rcg2: fix set_duty_cycle() integer overflow in boundary checks

From: Xilin Wu

Date: Mon Apr 06 2026 - 11:57:49 EST


The duty cycle boundary checks in clk_rcg2_set_duty_cycle() use
integer division to compare the 2d value against hardware limits:

if ((d / 2) > (n - m))
d = (n - m) * 2;
else if ((d / 2) < (m / 2))
d = m;

When d is odd, d/2 truncates, allowing values one beyond the hardware
maximum to pass. For example with n=7680, m=1, requesting 99.995%
duty:

d = 15359 (raw 2d value)
d / 2 = 7679 (truncated)
n - m = 7679
7679 > 7679 → false, check passes

But d=15359 exceeds the hardware limit of 2*(n-m)=15358. Writing this
invalid value causes the RCG to fail its configuration update, the
CMD_UPDATE bit never clears, and the clock output stops entirely.

The initial D value in __clk_rcg2_configure_mnd() correctly uses
direct comparison without division:

d_val = clamp_t(u32, d_val, f->m, 2 * (f->n - f->m));

Align set_duty_cycle() with the same bounds by comparing directly:

if (d > (n - m) * 2)
else if (d < m)

Fixes: 7f891faf596e ("clk: qcom: clk-rcg2: Add support for duty-cycle for RCG")
Signed-off-by: Xilin Wu <sophon@xxxxxxxxx>
---
drivers/clk/qcom/clk-rcg2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 732f34629ea2..153d2058c2a9 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -814,9 +814,9 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
*/
d = clamp_val(d, 1, mask);

- if ((d / 2) > (n - m))
+ if (d > (n - m) * 2)
d = (n - m) * 2;
- else if ((d / 2) < (m / 2))
+ else if (d < m)
d = m;

not2d = ~d & mask;

--
2.53.0