Commit ab248b60 authored by Mika Westerberg's avatar Mika Westerberg Committed by Thierry Reding

pwm: lpss: Prevent on_time_div overflow on lower frequencies

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: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent e5ca4245
...@@ -91,7 +91,7 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -91,7 +91,7 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns) int duty_ns, int period_ns)
{ {
struct pwm_lpss_chip *lpwm = to_lpwm(chip); 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 c, base_unit_range;
unsigned long long base_unit, freq = NSEC_PER_SEC; unsigned long long base_unit, freq = NSEC_PER_SEC;
u32 ctrl; u32 ctrl;
...@@ -113,7 +113,9 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -113,7 +113,9 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
if (duty_ns <= 0) if (duty_ns <= 0)
duty_ns = 1; 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); pm_runtime_get_sync(chip->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment