If the 'required_clk_rate' is greater than the clock rate that can be provided, then when mul_u64_u64_div_u64() is called to determine the 'rate' for the PWM divider, 0 will be returned. If 'rate' is 0, then we will return -EINVAL and fail to configure the PWM. Fix this by adding 1 to the PWM_DUTY_WIDTH when calculating the 'required_clk_rate' to ensure that 'rate' is greater or equal to 1. This fixes an issue on Tegra234 where configuring the PWM fan fails. Fixes: 8c193f4714df ("pwm: tegra: Optimize period calculation") Signed-off-by: Jon Hunter <jonathanh@xxxxxxxxxx> --- drivers/pwm/pwm-tegra.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 8a33c500f93b..973e2c1533ab 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -148,6 +148,19 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, required_clk_rate = DIV_ROUND_UP_ULL((NSEC_PER_SEC << PWM_DUTY_WIDTH), period_ns); + /* + * If the 'required_clk_rate' is greater than the clock rate + * that can be provided, then when mul_u64_u64_div_u64() is + * called to determine the 'rate' for the PWM divider, 0 will + * be returned. If 'rate' is 0, then we will return -EINVAL and + * fail to configure the PWM. If this case, add 1 to the + * PWM_DUTY_WIDTH when calculating the 'required_clk_rate' to + * ensure that 'rate' is greater or equal to 1. + */ + if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate)) + required_clk_rate = DIV_ROUND_UP_ULL((NSEC_PER_SEC << (PWM_DUTY_WIDTH + 1)), + period_ns); + err = dev_pm_opp_set_rate(pc->dev, required_clk_rate); if (err < 0) return -EINVAL; -- 2.25.1