All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] gpio: mvebu: pwm fixes and improvements
@ 2021-01-20 16:16 ` Baruch Siach
  0 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Baruch Siach, Andrew Lunn, Gregory Clement, Russell King,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio,
	linux-arm-kernel

This series adds a few related fixes to the pwm .apply and .get_state
callbacks.

The first patch was originally part of the series adding Armada 8K/7K pwm
support. I split it out to a separate series following review comments from
Uwe Kleine-König who spotted a few more issues. There is no dependency between
this and the Armada 8K/7K series.

v5:

  * Drop a patch applied to the gpio tree

  * Fix patch 4/4 description typo (Uwe)

  * Reduce the number of multiplications (Uwe)

  * Add spaces around '+' (Uwe)

  * Use '1ULL' instead of explicit cast to reduce verbosity

  * Add Linus' Reviewed-by tags to patches that are unchanged since v2

v4:

  * Take advantage of zero value being treated as 2^32 by hardware. Rewrite
    patch 5/5 (Uwe).

v3:

  * Improve patch 3/5 description (Uwe)

  * Add more Reviewed-by tags from Uwe

v2:

Address Uwe Kleine-König comments.

  * Improve patch 1/5 summary line

  * Add more information to patch 1/5 description

  * Add more information to patch 2/5 description

  * Don't round period/duty_cycle up in .apply (patch 3/5)

  * Expand the comment in path 5/5 based on RMK's analysis of hardware
    behaviour

  * Add Uwe's Reviewed-by tags

Baruch Siach (4):
  gpio: mvebu: improve pwm period calculation accuracy
  gpio: mvebu: make pwm .get_state closer to idempotent
  gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX
  gpio: mvebu: improve handling of pwm zero on/off values

 drivers/gpio/gpio-mvebu.c | 47 +++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 22 deletions(-)

-- 
2.29.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5 0/4] gpio: mvebu: pwm fixes and improvements
@ 2021-01-20 16:16 ` Baruch Siach
  0 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Andrew Lunn, Baruch Siach, linux-pwm, Gregory Clement,
	Russell King, linux-gpio, Chris Packham, Thomas Petazzoni,
	Ralph Sennhauser, Sascha Hauer, linux-arm-kernel,
	Sebastian Hesselbarth

This series adds a few related fixes to the pwm .apply and .get_state
callbacks.

The first patch was originally part of the series adding Armada 8K/7K pwm
support. I split it out to a separate series following review comments from
Uwe Kleine-König who spotted a few more issues. There is no dependency between
this and the Armada 8K/7K series.

v5:

  * Drop a patch applied to the gpio tree

  * Fix patch 4/4 description typo (Uwe)

  * Reduce the number of multiplications (Uwe)

  * Add spaces around '+' (Uwe)

  * Use '1ULL' instead of explicit cast to reduce verbosity

  * Add Linus' Reviewed-by tags to patches that are unchanged since v2

v4:

  * Take advantage of zero value being treated as 2^32 by hardware. Rewrite
    patch 5/5 (Uwe).

v3:

  * Improve patch 3/5 description (Uwe)

  * Add more Reviewed-by tags from Uwe

v2:

Address Uwe Kleine-König comments.

  * Improve patch 1/5 summary line

  * Add more information to patch 1/5 description

  * Add more information to patch 2/5 description

  * Don't round period/duty_cycle up in .apply (patch 3/5)

  * Expand the comment in path 5/5 based on RMK's analysis of hardware
    behaviour

  * Add Uwe's Reviewed-by tags

Baruch Siach (4):
  gpio: mvebu: improve pwm period calculation accuracy
  gpio: mvebu: make pwm .get_state closer to idempotent
  gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX
  gpio: mvebu: improve handling of pwm zero on/off values

 drivers/gpio/gpio-mvebu.c | 47 +++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 22 deletions(-)

-- 
2.29.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5 1/4] gpio: mvebu: improve pwm period calculation accuracy
  2021-01-20 16:16 ` Baruch Siach
@ 2021-01-20 16:16   ` Baruch Siach
  -1 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Baruch Siach, Andrew Lunn, Gregory Clement, Russell King,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio,
	linux-arm-kernel

Change 'off' register value calculation from

  $off = (period - duty_cycle) * clkrate / NSEC_PER_SEC

to

  $off = (period * clkrate / NSEC_PER_SEC) - $on

That is, divide the full period value to reduce rounding error.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index a912a8fed197..c424d88e9e2b 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -715,9 +715,9 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	else
 		on = 1;
 
-	val = (unsigned long long) mvpwm->clk_rate *
-		(state->period - state->duty_cycle);
+	val = (unsigned long long) mvpwm->clk_rate * state->period;
 	do_div(val, NSEC_PER_SEC);
+	val -= on;
 	if (val > UINT_MAX)
 		return -EINVAL;
 	if (val)
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 1/4] gpio: mvebu: improve pwm period calculation accuracy
@ 2021-01-20 16:16   ` Baruch Siach
  0 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Andrew Lunn, Baruch Siach, linux-pwm, Gregory Clement,
	Russell King, linux-gpio, Chris Packham, Thomas Petazzoni,
	Ralph Sennhauser, Sascha Hauer, linux-arm-kernel,
	Sebastian Hesselbarth

Change 'off' register value calculation from

  $off = (period - duty_cycle) * clkrate / NSEC_PER_SEC

to

  $off = (period * clkrate / NSEC_PER_SEC) - $on

That is, divide the full period value to reduce rounding error.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index a912a8fed197..c424d88e9e2b 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -715,9 +715,9 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	else
 		on = 1;
 
-	val = (unsigned long long) mvpwm->clk_rate *
-		(state->period - state->duty_cycle);
+	val = (unsigned long long) mvpwm->clk_rate * state->period;
 	do_div(val, NSEC_PER_SEC);
+	val -= on;
 	if (val > UINT_MAX)
 		return -EINVAL;
 	if (val)
-- 
2.29.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 2/4] gpio: mvebu: make pwm .get_state closer to idempotent
  2021-01-20 16:16 ` Baruch Siach
@ 2021-01-20 16:16   ` Baruch Siach
  -1 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Baruch Siach, Andrew Lunn, Gregory Clement, Russell King,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio,
	linux-arm-kernel

Round up the divisions in .get_state() to make applying the read out
configuration idempotent in most cases as .apply rounds down.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index c424d88e9e2b..8673ba77af5a 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -668,7 +668,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_on_duration(mvpwm), &u);
 	val = (unsigned long long) u * NSEC_PER_SEC;
-	do_div(val, mvpwm->clk_rate);
+	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
 	if (val > UINT_MAX)
 		state->duty_cycle = UINT_MAX;
 	else if (val)
@@ -680,7 +680,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u);
 	val += (unsigned long long) u; /* period = on + off duration */
 	val *= NSEC_PER_SEC;
-	do_div(val, mvpwm->clk_rate);
+	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
 	if (val > UINT_MAX)
 		state->period = UINT_MAX;
 	else if (val)
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 2/4] gpio: mvebu: make pwm .get_state closer to idempotent
@ 2021-01-20 16:16   ` Baruch Siach
  0 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Andrew Lunn, Baruch Siach, linux-pwm, Gregory Clement,
	Russell King, linux-gpio, Chris Packham, Thomas Petazzoni,
	Ralph Sennhauser, Sascha Hauer, linux-arm-kernel,
	Sebastian Hesselbarth

Round up the divisions in .get_state() to make applying the read out
configuration idempotent in most cases as .apply rounds down.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index c424d88e9e2b..8673ba77af5a 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -668,7 +668,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_on_duration(mvpwm), &u);
 	val = (unsigned long long) u * NSEC_PER_SEC;
-	do_div(val, mvpwm->clk_rate);
+	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
 	if (val > UINT_MAX)
 		state->duty_cycle = UINT_MAX;
 	else if (val)
@@ -680,7 +680,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u);
 	val += (unsigned long long) u; /* period = on + off duration */
 	val *= NSEC_PER_SEC;
-	do_div(val, mvpwm->clk_rate);
+	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
 	if (val > UINT_MAX)
 		state->period = UINT_MAX;
 	else if (val)
-- 
2.29.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 3/4] gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX
  2021-01-20 16:16 ` Baruch Siach
@ 2021-01-20 16:16   ` Baruch Siach
  -1 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Baruch Siach, Andrew Lunn, Gregory Clement, Russell King,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio,
	linux-arm-kernel

PWM on/off registers are limited to UINT_MAX. However the state period
and duty_cycle fields are ns values of type u64. There is no reason to
limit them to UINT_MAX.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 8673ba77af5a..6b017854ce61 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -669,9 +669,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_on_duration(mvpwm), &u);
 	val = (unsigned long long) u * NSEC_PER_SEC;
 	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val > UINT_MAX)
-		state->duty_cycle = UINT_MAX;
-	else if (val)
+	if (val)
 		state->duty_cycle = val;
 	else
 		state->duty_cycle = 1;
@@ -681,9 +679,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	val += (unsigned long long) u; /* period = on + off duration */
 	val *= NSEC_PER_SEC;
 	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val > UINT_MAX)
-		state->period = UINT_MAX;
-	else if (val)
+	if (val)
 		state->period = val;
 	else
 		state->period = 1;
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 3/4] gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX
@ 2021-01-20 16:16   ` Baruch Siach
  0 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Andrew Lunn, Baruch Siach, linux-pwm, Gregory Clement,
	Russell King, linux-gpio, Chris Packham, Thomas Petazzoni,
	Ralph Sennhauser, Sascha Hauer, linux-arm-kernel,
	Sebastian Hesselbarth

PWM on/off registers are limited to UINT_MAX. However the state period
and duty_cycle fields are ns values of type u64. There is no reason to
limit them to UINT_MAX.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 8673ba77af5a..6b017854ce61 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -669,9 +669,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_on_duration(mvpwm), &u);
 	val = (unsigned long long) u * NSEC_PER_SEC;
 	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val > UINT_MAX)
-		state->duty_cycle = UINT_MAX;
-	else if (val)
+	if (val)
 		state->duty_cycle = val;
 	else
 		state->duty_cycle = 1;
@@ -681,9 +679,7 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	val += (unsigned long long) u; /* period = on + off duration */
 	val *= NSEC_PER_SEC;
 	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val > UINT_MAX)
-		state->period = UINT_MAX;
-	else if (val)
+	if (val)
 		state->period = val;
 	else
 		state->period = 1;
-- 
2.29.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 4/4] gpio: mvebu: improve handling of pwm zero on/off values
  2021-01-20 16:16 ` Baruch Siach
@ 2021-01-20 16:16   ` Baruch Siach
  -1 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Baruch Siach, Russell King, Andrew Lunn, Gregory Clement,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio,
	linux-arm-kernel

Hardware appears to treat zero value as 2^32. Take advantage of this
fact to support on/off values of up to UINT_MAX+1 == 2^32. Adjust both
.apply and .get_state to handle zero as a special case.

Rounded up division result in .get_state can't be zero, since the
dividend is now larger than 0. Remove check for this case.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Analyzed-by: Russell King <linux@armlinux.org.uk>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 6b017854ce61..75e3c235bd3a 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -667,22 +667,21 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	spin_lock_irqsave(&mvpwm->lock, flags);
 
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_on_duration(mvpwm), &u);
-	val = (unsigned long long) u * NSEC_PER_SEC;
-	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val)
-		state->duty_cycle = val;
+	/* Hardware treats zero as 2^32. See mvebu_pwm_apply(). */
+	if (u > 0)
+		val = u;
 	else
-		state->duty_cycle = 1;
+		val = UINT_MAX + 1ULL;
+	state->duty_cycle = DIV_ROUND_UP_ULL(val * NSEC_PER_SEC,
+			mvpwm->clk_rate);
 
-	val = (unsigned long long) u; /* on duration */
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u);
-	val += (unsigned long long) u; /* period = on + off duration */
-	val *= NSEC_PER_SEC;
-	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val)
-		state->period = val;
+	/* period = on + off duration */
+	if (u > 0)
+		val += u;
 	else
-		state->period = 1;
+		val += UINT_MAX + 1ULL;
+	state->period = DIV_ROUND_UP_ULL(val * NSEC_PER_SEC, mvpwm->clk_rate);
 
 	regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u);
 	if (u)
@@ -704,9 +703,15 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	val = (unsigned long long) mvpwm->clk_rate * state->duty_cycle;
 	do_div(val, NSEC_PER_SEC);
-	if (val > UINT_MAX)
+	if (val > UINT_MAX + 1ULL)
 		return -EINVAL;
-	if (val)
+	/*
+	 * Zero on/off values don't work as expected. Experimentation shows
+	 * that zero value is treated as 2^32. This behavior is not documented.
+	 */
+	if (val == UINT_MAX + 1ULL)
+		on = 0;
+	else if (val)
 		on = val;
 	else
 		on = 1;
@@ -714,9 +719,11 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	val = (unsigned long long) mvpwm->clk_rate * state->period;
 	do_div(val, NSEC_PER_SEC);
 	val -= on;
-	if (val > UINT_MAX)
+	if (val > UINT_MAX + 1ULL)
 		return -EINVAL;
-	if (val)
+	if (val == UINT_MAX + 1ULL)
+		off = 0;
+	else if (val)
 		off = val;
 	else
 		off = 1;
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v5 4/4] gpio: mvebu: improve handling of pwm zero on/off values
@ 2021-01-20 16:16   ` Baruch Siach
  0 siblings, 0 replies; 14+ messages in thread
From: Baruch Siach @ 2021-01-20 16:16 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Bartosz Golaszewski
  Cc: Andrew Lunn, Baruch Siach, linux-pwm, Gregory Clement,
	Russell King, linux-gpio, Chris Packham, Thomas Petazzoni,
	Ralph Sennhauser, Sascha Hauer, linux-arm-kernel,
	Sebastian Hesselbarth

Hardware appears to treat zero value as 2^32. Take advantage of this
fact to support on/off values of up to UINT_MAX+1 == 2^32. Adjust both
.apply and .get_state to handle zero as a special case.

Rounded up division result in .get_state can't be zero, since the
dividend is now larger than 0. Remove check for this case.

Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Analyzed-by: Russell King <linux@armlinux.org.uk>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/gpio/gpio-mvebu.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 6b017854ce61..75e3c235bd3a 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -667,22 +667,21 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
 	spin_lock_irqsave(&mvpwm->lock, flags);
 
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_on_duration(mvpwm), &u);
-	val = (unsigned long long) u * NSEC_PER_SEC;
-	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val)
-		state->duty_cycle = val;
+	/* Hardware treats zero as 2^32. See mvebu_pwm_apply(). */
+	if (u > 0)
+		val = u;
 	else
-		state->duty_cycle = 1;
+		val = UINT_MAX + 1ULL;
+	state->duty_cycle = DIV_ROUND_UP_ULL(val * NSEC_PER_SEC,
+			mvpwm->clk_rate);
 
-	val = (unsigned long long) u; /* on duration */
 	regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u);
-	val += (unsigned long long) u; /* period = on + off duration */
-	val *= NSEC_PER_SEC;
-	val = DIV_ROUND_UP_ULL(val, mvpwm->clk_rate);
-	if (val)
-		state->period = val;
+	/* period = on + off duration */
+	if (u > 0)
+		val += u;
 	else
-		state->period = 1;
+		val += UINT_MAX + 1ULL;
+	state->period = DIV_ROUND_UP_ULL(val * NSEC_PER_SEC, mvpwm->clk_rate);
 
 	regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u);
 	if (u)
@@ -704,9 +703,15 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 
 	val = (unsigned long long) mvpwm->clk_rate * state->duty_cycle;
 	do_div(val, NSEC_PER_SEC);
-	if (val > UINT_MAX)
+	if (val > UINT_MAX + 1ULL)
 		return -EINVAL;
-	if (val)
+	/*
+	 * Zero on/off values don't work as expected. Experimentation shows
+	 * that zero value is treated as 2^32. This behavior is not documented.
+	 */
+	if (val == UINT_MAX + 1ULL)
+		on = 0;
+	else if (val)
 		on = val;
 	else
 		on = 1;
@@ -714,9 +719,11 @@ static int mvebu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	val = (unsigned long long) mvpwm->clk_rate * state->period;
 	do_div(val, NSEC_PER_SEC);
 	val -= on;
-	if (val > UINT_MAX)
+	if (val > UINT_MAX + 1ULL)
 		return -EINVAL;
-	if (val)
+	if (val == UINT_MAX + 1ULL)
+		off = 0;
+	else if (val)
 		off = val;
 	else
 		off = 1;
-- 
2.29.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 4/4] gpio: mvebu: improve handling of pwm zero on/off values
  2021-01-20 16:16   ` Baruch Siach
@ 2021-01-20 17:24     ` Uwe Kleine-König
  -1 siblings, 0 replies; 14+ messages in thread
From: Uwe Kleine-König @ 2021-01-20 17:24 UTC (permalink / raw)
  To: Baruch Siach
  Cc: Thierry Reding, Lee Jones, Linus Walleij, Bartosz Golaszewski,
	Russell King, Andrew Lunn, Gregory Clement,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio,
	linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 817 bytes --]

On Wed, Jan 20, 2021 at 06:16:28PM +0200, Baruch Siach wrote:
> Hardware appears to treat zero value as 2^32. Take advantage of this
> fact to support on/off values of up to UINT_MAX+1 == 2^32. Adjust both
> .apply and .get_state to handle zero as a special case.
> 
> Rounded up division result in .get_state can't be zero, since the
> dividend is now larger than 0. Remove check for this case.
> 
> Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> Analyzed-by: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>

Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 4/4] gpio: mvebu: improve handling of pwm zero on/off values
@ 2021-01-20 17:24     ` Uwe Kleine-König
  0 siblings, 0 replies; 14+ messages in thread
From: Uwe Kleine-König @ 2021-01-20 17:24 UTC (permalink / raw)
  To: Baruch Siach
  Cc: Andrew Lunn, Sascha Hauer, linux-pwm, Linus Walleij,
	Chris Packham, Russell King, Bartosz Golaszewski, Thierry Reding,
	Thomas Petazzoni, linux-gpio, Ralph Sennhauser, Lee Jones,
	Gregory Clement, linux-arm-kernel, Sebastian Hesselbarth


[-- Attachment #1.1: Type: text/plain, Size: 817 bytes --]

On Wed, Jan 20, 2021 at 06:16:28PM +0200, Baruch Siach wrote:
> Hardware appears to treat zero value as 2^32. Take advantage of this
> fact to support on/off values of up to UINT_MAX+1 == 2^32. Adjust both
> .apply and .get_state to handle zero as a special case.
> 
> Rounded up division result in .get_state can't be zero, since the
> dividend is now larger than 0. Remove check for this case.
> 
> Reported-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> Analyzed-by: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>

Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 0/4] gpio: mvebu: pwm fixes and improvements
  2021-01-20 16:16 ` Baruch Siach
@ 2021-01-25  9:43   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 14+ messages in thread
From: Bartosz Golaszewski @ 2021-01-25  9:43 UTC (permalink / raw)
  To: Baruch Siach
  Cc: Thierry Reding, Uwe Kleine-König, Lee Jones, Linus Walleij,
	Andrew Lunn, Gregory Clement, Russell King,
	Sebastian Hesselbarth, Thomas Petazzoni, Chris Packham,
	Sascha Hauer, Ralph Sennhauser, linux-pwm, linux-gpio, arm-soc

On Wed, Jan 20, 2021 at 5:16 PM Baruch Siach <baruch@tkos.co.il> wrote:
>
> This series adds a few related fixes to the pwm .apply and .get_state
> callbacks.
>
> The first patch was originally part of the series adding Armada 8K/7K pwm
> support. I split it out to a separate series following review comments from
> Uwe Kleine-König who spotted a few more issues. There is no dependency between
> this and the Armada 8K/7K series.
>
> v5:
>
>   * Drop a patch applied to the gpio tree
>
>   * Fix patch 4/4 description typo (Uwe)
>
>   * Reduce the number of multiplications (Uwe)
>
>   * Add spaces around '+' (Uwe)
>
>   * Use '1ULL' instead of explicit cast to reduce verbosity
>
>   * Add Linus' Reviewed-by tags to patches that are unchanged since v2
>
> v4:
>
>   * Take advantage of zero value being treated as 2^32 by hardware. Rewrite
>     patch 5/5 (Uwe).
>
> v3:
>
>   * Improve patch 3/5 description (Uwe)
>
>   * Add more Reviewed-by tags from Uwe
>
> v2:
>
> Address Uwe Kleine-König comments.
>
>   * Improve patch 1/5 summary line
>
>   * Add more information to patch 1/5 description
>
>   * Add more information to patch 2/5 description
>
>   * Don't round period/duty_cycle up in .apply (patch 3/5)
>
>   * Expand the comment in path 5/5 based on RMK's analysis of hardware
>     behaviour
>
>   * Add Uwe's Reviewed-by tags
>
> Baruch Siach (4):
>   gpio: mvebu: improve pwm period calculation accuracy
>   gpio: mvebu: make pwm .get_state closer to idempotent
>   gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX
>   gpio: mvebu: improve handling of pwm zero on/off values
>
>  drivers/gpio/gpio-mvebu.c | 47 +++++++++++++++++++++------------------
>  1 file changed, 25 insertions(+), 22 deletions(-)
>
> --
> 2.29.2
>

Series applied, thanks a lot for the improvements! And thanks to Uwe
and Russel for the reviews.

Bartosz

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v5 0/4] gpio: mvebu: pwm fixes and improvements
@ 2021-01-25  9:43   ` Bartosz Golaszewski
  0 siblings, 0 replies; 14+ messages in thread
From: Bartosz Golaszewski @ 2021-01-25  9:43 UTC (permalink / raw)
  To: Baruch Siach
  Cc: Andrew Lunn, Sascha Hauer, linux-pwm, Linus Walleij,
	Chris Packham, Russell King, linux-gpio, Thierry Reding,
	Thomas Petazzoni, Uwe Kleine-König, Ralph Sennhauser,
	Lee Jones, Gregory Clement, arm-soc, Sebastian Hesselbarth

On Wed, Jan 20, 2021 at 5:16 PM Baruch Siach <baruch@tkos.co.il> wrote:
>
> This series adds a few related fixes to the pwm .apply and .get_state
> callbacks.
>
> The first patch was originally part of the series adding Armada 8K/7K pwm
> support. I split it out to a separate series following review comments from
> Uwe Kleine-König who spotted a few more issues. There is no dependency between
> this and the Armada 8K/7K series.
>
> v5:
>
>   * Drop a patch applied to the gpio tree
>
>   * Fix patch 4/4 description typo (Uwe)
>
>   * Reduce the number of multiplications (Uwe)
>
>   * Add spaces around '+' (Uwe)
>
>   * Use '1ULL' instead of explicit cast to reduce verbosity
>
>   * Add Linus' Reviewed-by tags to patches that are unchanged since v2
>
> v4:
>
>   * Take advantage of zero value being treated as 2^32 by hardware. Rewrite
>     patch 5/5 (Uwe).
>
> v3:
>
>   * Improve patch 3/5 description (Uwe)
>
>   * Add more Reviewed-by tags from Uwe
>
> v2:
>
> Address Uwe Kleine-König comments.
>
>   * Improve patch 1/5 summary line
>
>   * Add more information to patch 1/5 description
>
>   * Add more information to patch 2/5 description
>
>   * Don't round period/duty_cycle up in .apply (patch 3/5)
>
>   * Expand the comment in path 5/5 based on RMK's analysis of hardware
>     behaviour
>
>   * Add Uwe's Reviewed-by tags
>
> Baruch Siach (4):
>   gpio: mvebu: improve pwm period calculation accuracy
>   gpio: mvebu: make pwm .get_state closer to idempotent
>   gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX
>   gpio: mvebu: improve handling of pwm zero on/off values
>
>  drivers/gpio/gpio-mvebu.c | 47 +++++++++++++++++++++------------------
>  1 file changed, 25 insertions(+), 22 deletions(-)
>
> --
> 2.29.2
>

Series applied, thanks a lot for the improvements! And thanks to Uwe
and Russel for the reviews.

Bartosz

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-01-26  5:25 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-20 16:16 [PATCH v5 0/4] gpio: mvebu: pwm fixes and improvements Baruch Siach
2021-01-20 16:16 ` Baruch Siach
2021-01-20 16:16 ` [PATCH v5 1/4] gpio: mvebu: improve pwm period calculation accuracy Baruch Siach
2021-01-20 16:16   ` Baruch Siach
2021-01-20 16:16 ` [PATCH v5 2/4] gpio: mvebu: make pwm .get_state closer to idempotent Baruch Siach
2021-01-20 16:16   ` Baruch Siach
2021-01-20 16:16 ` [PATCH v5 3/4] gpio: mvebu: don't limit pwm period/duty_cycle to UINT_MAX Baruch Siach
2021-01-20 16:16   ` Baruch Siach
2021-01-20 16:16 ` [PATCH v5 4/4] gpio: mvebu: improve handling of pwm zero on/off values Baruch Siach
2021-01-20 16:16   ` Baruch Siach
2021-01-20 17:24   ` Uwe Kleine-König
2021-01-20 17:24     ` Uwe Kleine-König
2021-01-25  9:43 ` [PATCH v5 0/4] gpio: mvebu: pwm fixes and improvements Bartosz Golaszewski
2021-01-25  9:43   ` Bartosz Golaszewski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.