summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2020-03-29 12:24:59 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2020-06-29 01:19:46 +0100
commit98c99b4e046b09271e3e37cd4577654be1a6f8ea (patch)
treee928556d47d2f1c2c1fdeea06868bbc5d57915f7
parent3c03c057f5dbde0859ca02d7d451bc6bb98370ae (diff)
gpio: mvebu: fix PWM period calculation
The period of a PWM signal is the sum of the on and off durations. The calculation being used by gpio-mvebu is not correct, resulting in the period being miscalculated and invalid. Fix this. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/gpio/gpio-mvebu.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index bd65114eb170..8399ff02c243 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -660,8 +660,8 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
spin_lock_irqsave(&mvpwm->lock, flags);
- val = (unsigned long long)
- readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
+ u = readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
+ val = u;
val *= NSEC_PER_SEC;
do_div(val, mvpwm->clk_rate);
if (val > UINT_MAX)
@@ -671,21 +671,17 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
else
state->duty_cycle = 1;
- val = (unsigned long long)
- readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
+ val = u;
+ u = readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
+ val += u;
val *= NSEC_PER_SEC;
do_div(val, mvpwm->clk_rate);
- if (val < state->duty_cycle) {
+ if (val > UINT_MAX)
+ state->period = UINT_MAX;
+ else if (val)
+ state->period = val;
+ else
state->period = 1;
- } else {
- val -= state->duty_cycle;
- if (val > UINT_MAX)
- state->period = UINT_MAX;
- else if (val)
- state->period = val;
- else
- state->period = 1;
- }
regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u);
if (u)