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

pwm: mediatek: Prevent divide-by-zero in pwm_mediatek_config()

With CONFIG_COMPILE_TEST && !CONFIG_HAVE_CLK, pwm_mediatek_config() has a
divide-by-zero in the following line:

do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm]));

due to the fact that the !CONFIG_HAVE_CLK version of clk_get_rate()
returns zero.

This is presumably just a theoretical problem: COMPILE_TEST overrides
the dependency on RALINK which would select COMMON_CLK. Regardless it's
a good idea to check for the error explicitly to avoid divide-by-zero.

Fixes the following warning:

drivers/pwm/pwm-mediatek.o: warning: objtool: .text: unexpected end of section

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Link: https://lore.kernel.org/r/fb56444939325cc173e752ba199abd7aeae3bf12.1742852847.git.jpoimboe@kernel.org
[ukleinek: s/CONFIG_CLK/CONFIG_HAVE_CLK/]
Fixes: caf065f8fd58 ("pwm: Add MediaTek PWM support")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/9e78a0796acba3435553ed7db1c7965dcffa6215.1743501688.git.u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>

authored by

Josh Poimboeuf and committed by
Uwe Kleine-König
7ca59947 6df320ab

+6 -2
+6 -2
drivers/pwm/pwm-mediatek.c
··· 121 121 struct pwm_mediatek_chip *pc = to_pwm_mediatek_chip(chip); 122 122 u32 clkdiv = 0, cnt_period, cnt_duty, reg_width = PWMDWIDTH, 123 123 reg_thres = PWMTHRES; 124 + unsigned long clk_rate; 124 125 u64 resolution; 125 126 int ret; 126 127 127 128 ret = pwm_mediatek_clk_enable(chip, pwm); 128 - 129 129 if (ret < 0) 130 130 return ret; 131 + 132 + clk_rate = clk_get_rate(pc->clk_pwms[pwm->hwpwm]); 133 + if (!clk_rate) 134 + return -EINVAL; 131 135 132 136 /* Make sure we use the bus clock and not the 26MHz clock */ 133 137 if (pc->soc->has_ck_26m_sel) ··· 139 135 140 136 /* Using resolution in picosecond gets accuracy higher */ 141 137 resolution = (u64)NSEC_PER_SEC * 1000; 142 - do_div(resolution, clk_get_rate(pc->clk_pwms[pwm->hwpwm])); 138 + do_div(resolution, clk_rate); 143 139 144 140 cnt_period = DIV_ROUND_CLOSEST_ULL((u64)period_ns * 1000, resolution); 145 141 while (cnt_period > 8191) {