--- /dev/null
+From e73b0101ae5124bf7cd3fb5d250302ad2f16a416 Mon Sep 17 00:00:00 2001
+From: Baruch Siach <baruch@tkos.co.il>
+Date: Sun, 17 Jan 2021 15:17:02 +0200
+Subject: gpio: mvebu: fix pwm .get_state period calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Baruch Siach <baruch@tkos.co.il>
+
+commit e73b0101ae5124bf7cd3fb5d250302ad2f16a416 upstream.
+
+The period is the sum of on and off values. That is, calculate period as
+
+ ($on + $off) / clkrate
+
+instead of
+
+ $off / clkrate - $on / clkrate
+
+that makes no sense.
+
+Reported-by: Russell King <linux@armlinux.org.uk>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Fixes: 757642f9a584e ("gpio: mvebu: Add limited PWM support")
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+[baruch: backport to kernels <= v5.10]
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpio-mvebu.c | 25 ++++++++++---------------
+ 1 file changed, 10 insertions(+), 15 deletions(-)
+
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -650,9 +650,8 @@ static void mvebu_pwm_get_state(struct p
+
+ spin_lock_irqsave(&mvpwm->lock, flags);
+
+- val = (unsigned long long)
+- readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
+- val *= NSEC_PER_SEC;
++ u = readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm));
++ val = (unsigned long long) u * NSEC_PER_SEC;
+ do_div(val, mvpwm->clk_rate);
+ if (val > UINT_MAX)
+ state->duty_cycle = UINT_MAX;
+@@ -661,21 +660,17 @@ static void mvebu_pwm_get_state(struct p
+ else
+ state->duty_cycle = 1;
+
+- val = (unsigned long long)
+- readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
++ val = (unsigned long long) u; /* on duration */
++ /* period = on + off duration */
++ val += readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm));
+ 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)