pwm: tegra: Avoid overflow when calculating duty cycle
authorHyong Bin Kim <hyongbink@nvidia.com>
Wed, 22 Jun 2016 11:47:21 +0000 (17:17 +0530)
committerThierry Reding <thierry.reding@gmail.com>
Mon, 11 Jul 2016 10:49:32 +0000 (12:49 +0200)
duty_ns * (1 << PWM_DUTY_WIDTH) could overflow in integer calculation
when the PWM rate is low. Hence do all calculation on unsigned long long
to avoid overflow.

Signed-off-by: Hyong Bin Kim <hyongbink@nvidia.com>
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-tegra.c

index 2026eaa932ae576d4adcad8bbd84f8417df7a02d..247156149b448b214d075930dd7a42cab039eb76 100644 (file)
@@ -67,7 +67,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                            int duty_ns, int period_ns)
 {
        struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
-       unsigned long long c;
+       unsigned long long c = duty_ns;
        unsigned long rate, hz;
        u32 val = 0;
        int err;
@@ -77,7 +77,8 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
         * per (1 << PWM_DUTY_WIDTH) cycles and make sure to round to the
         * nearest integer during division.
         */
-       c = duty_ns * (1 << PWM_DUTY_WIDTH) + period_ns / 2;
+       c *= (1 << PWM_DUTY_WIDTH);
+       c += period_ns / 2;
        do_div(c, period_ns);
 
        val = (u32)c << PWM_DUTY_SHIFT;