aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm
diff options
context:
space:
mode:
authorJitao Shi <jitao.shi@mediatek.com>2021-08-08 21:24:32 +0800
committerThierry Reding <thierry.reding@gmail.com>2021-09-02 22:27:44 +0200
commit331e049dec64c2d269648a3ea4ea6aae8a54b4ac (patch)
treeba043dde61cc93e9de83767f64334d26fcae5d2b /drivers/pwm
parentpwm: mtk-disp: Implement atomic API .apply() (diff)
downloadlinux-dev-331e049dec64c2d269648a3ea4ea6aae8a54b4ac.tar.xz
linux-dev-331e049dec64c2d269648a3ea4ea6aae8a54b4ac.zip
pwm: mtk-disp: Fix overflow in period and duty calculation
Current calculation for period and high_width may have 64-bit overflow. state->period and rate are u64. rate * state->period will overflow. clk_div = div_u64(rate * state->period, NSEC_PER_SEC) period = div64_u64(rate * state->period, div); high_width = div64_u64(rate * state->duty_cycle, div); This patch is to resolve it by using mul_u64_u64_div_u64(). Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r--drivers/pwm/pwm-mtk-disp.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index caabcb30f90e..73f8103a782c 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -119,7 +119,7 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
* high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
*/
rate = clk_get_rate(mdp->clk_main);
- clk_div = div_u64(rate * state->period, NSEC_PER_SEC) >>
+ clk_div = mul_u64_u64_div_u64(state->period, rate, NSEC_PER_SEC) >>
PWM_PERIOD_BIT_WIDTH;
if (clk_div > PWM_CLKDIV_MAX) {
if (!mdp->enabled) {
@@ -130,11 +130,11 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
}
div = NSEC_PER_SEC * (clk_div + 1);
- period = div64_u64(rate * state->period, div);
+ period = mul_u64_u64_div_u64(state->period, rate, div);
if (period > 0)
period--;
- high_width = div64_u64(rate * state->duty_cycle, div);
+ high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
mtk_disp_pwm_update_bits(mdp, mdp->data->con0,