From: Mika Westerberg <mika.westerb...@linux.intel.com>

If duty_ns is large enough multiplying it by 255 overflows and results
wrong duty cycle value being programmed. For example with 10ms duty when
period is 20ms (50%) we get

  255 * 10000000 / 20000000 = -87

because 255 * 10000000 overlows int. Whereas correct value should be

  255 * 10000000 / 20000000 = 127

Fix this by using unsigned long long as type for on_time_div and changing
integer literals to use proper type annotation.

Signed-off-by: Mika Westerberg <mika.westerb...@linux.intel.com>
---
 drivers/pwm/pwm-lpss.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 98dc8b80b79d..be4658b42882 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -91,7 +91,7 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct 
pwm_device *pwm,
                           int duty_ns, int period_ns)
 {
        struct pwm_lpss_chip *lpwm = to_lpwm(chip);
-       u8 on_time_div;
+       unsigned long long on_time_div;
        unsigned long c, base_unit_range;
        unsigned long long base_unit, freq = NSEC_PER_SEC;
        u32 ctrl;
@@ -113,7 +113,9 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct 
pwm_device *pwm,
 
        if (duty_ns <= 0)
                duty_ns = 1;
-       on_time_div = 255 - (255 * duty_ns / period_ns);
+       on_time_div = 255ULL * duty_ns;
+       do_div(on_time_div, period_ns);
+       on_time_div = 255ULL - on_time_div;
 
        pm_runtime_get_sync(chip->dev);
 
-- 
1.9.1

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to