Linux PWM subsystem development
 help / color / mirror / Atom feed
* [PATCH 0/6] pwm: Some fixes preparing chardev support
@ 2025-04-05  9:27 Uwe Kleine-König
  2025-04-05  9:27 ` [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up Uwe Kleine-König
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm
  Cc: linux-kernel, Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue,
	linux-stm32, linux-arm-kernel, Michael Hennerich, Nuno Sá,
	Trevor Gamblin

Hello,

while working on character device support for PWMs I found a few
inconsistencies that are fixed in this series. After that I plan to work
on getting the character device support into shape to get it into
mainline, too.

While some of these patches qualify as fixes I think there is no urge to
get them into 6.15, but given there is a bunch of such changes I might
send them to all together to Linus for inclusion to 6.15.

Best regards
Uwe

Uwe Kleine-König (6):
  pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
  pwm: stm32: Search an appropriate duty_cycle if period cannot be
    modified
  pwm: stm32: Don't open-code TIM_CCER_CCxE()
  pwm: stm32: Emit debug output also for corner cases of the rounding
    callbacks
  pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was
    rounded up
  pwm: Do stricter return value checking for .round_waveform_tohw()

 drivers/pwm/core.c           | 23 ++++++++++++-----------
 drivers/pwm/pwm-axi-pwmgen.c | 10 +++++++---
 drivers/pwm/pwm-stm32.c      | 25 +++++++++----------------
 3 files changed, 28 insertions(+), 30 deletions(-)

base-commit: e48e99b6edf41c69c5528aa7ffb2daf3c59ee105
-- 
2.47.2


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

* [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
@ 2025-04-05  9:27 ` Uwe Kleine-König
  2025-04-07 12:52   ` Trevor Gamblin
  2025-04-05  9:27 ` [PATCH 2/6] pwm: stm32: Search an appropriate duty_cycle if period cannot be modified Uwe Kleine-König
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm; +Cc: linux-kernel

Waveform parameters are supposed to be rounded down to the next value
possible for the hardware. However when a requested value is too small,
.round_waveform_tohw() is supposed to pick the next bigger value and
return 1. Let pwm_set_waveform() behave in the same way.

This creates consistency between pwm_set_waveform_might_sleep() with
exact=false and pwm_round_waveform_might_sleep() +
pwm_set_waveform_might_sleep() with exact=true.

The PWM_DEBUG rounding check has to be adapted to only trigger if no
uprounding happend.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
 drivers/pwm/core.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a40c511e0096..0387bd838487 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -322,7 +322,7 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
 	const struct pwm_ops *ops = chip->ops;
 	char wfhw[WFHWSIZE];
 	struct pwm_waveform wf_rounded;
-	int err;
+	int err, ret_tohw;
 
 	BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
 
@@ -332,16 +332,16 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
 	if (!pwm_wf_valid(wf))
 		return -EINVAL;
 
-	err = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw);
-	if (err)
-		return err;
+	ret_tohw = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw);
+	if (ret_tohw < 0)
+		return ret_tohw;
 
 	if ((IS_ENABLED(CONFIG_PWM_DEBUG) || exact) && wf->period_length_ns) {
 		err = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf_rounded);
 		if (err)
 			return err;
 
-		if (IS_ENABLED(CONFIG_PWM_DEBUG) && !pwm_check_rounding(wf, &wf_rounded))
+		if (IS_ENABLED(CONFIG_PWM_DEBUG) && ret_tohw == 0 && !pwm_check_rounding(wf, &wf_rounded))
 			dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu]\n",
 				wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
 				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns);
@@ -382,7 +382,8 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
 				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns,
 				wf_set.duty_length_ns, wf_set.period_length_ns, wf_set.duty_offset_ns);
 	}
-	return 0;
+
+	return ret_tohw;
 }
 
 /**
-- 
2.47.2


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

* [PATCH 2/6] pwm: stm32: Search an appropriate duty_cycle if period cannot be modified
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
  2025-04-05  9:27 ` [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up Uwe Kleine-König
@ 2025-04-05  9:27 ` Uwe Kleine-König
  2025-04-05  9:27 ` [PATCH 3/6] pwm: stm32: Don't open-code TIM_CCER_CCxE() Uwe Kleine-König
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm
  Cc: Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue, linux-stm32,
	linux-arm-kernel, linux-kernel

If another channel is already enabled period must not be modified. If
the requested period is smaller than this unchangable period the driver
is still supposed to search a duty_cycle according to the usual rounding
rules.

So don't set the duty_cycle to 0 but continue to determine an
appropriate value for ccr.

Fixes: deaba9cff809 ("pwm: stm32: Implementation of the waveform callbacks")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
 drivers/pwm/pwm-stm32.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index a59de4de18b6..ec2c05c9ee7a 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -103,22 +103,16 @@ static int stm32_pwm_round_waveform_tohw(struct pwm_chip *chip,
 		if (ret)
 			goto out;
 
-		/*
-		 * calculate the best value for ARR for the given PSC, refuse if
-		 * the resulting period gets bigger than the requested one.
-		 */
 		arr = mul_u64_u64_div_u64(wf->period_length_ns, rate,
 					  (u64)NSEC_PER_SEC * (wfhw->psc + 1));
 		if (arr <= wfhw->arr) {
 			/*
-			 * requested period is small than the currently
+			 * requested period is smaller than the currently
 			 * configured and unchangable period, report back the smallest
-			 * possible period, i.e. the current state; Initialize
-			 * ccr to anything valid.
+			 * possible period, i.e. the current state and return 1
+			 * to indicate the wrong rounding direction.
 			 */
-			wfhw->ccr = 0;
 			ret = 1;
-			goto out;
 		}
 
 	} else {
-- 
2.47.2


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

* [PATCH 3/6] pwm: stm32: Don't open-code TIM_CCER_CCxE()
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
  2025-04-05  9:27 ` [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up Uwe Kleine-König
  2025-04-05  9:27 ` [PATCH 2/6] pwm: stm32: Search an appropriate duty_cycle if period cannot be modified Uwe Kleine-König
@ 2025-04-05  9:27 ` Uwe Kleine-König
  2025-04-05  9:27 ` [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks Uwe Kleine-König
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm
  Cc: Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue, linux-stm32,
	linux-arm-kernel, linux-kernel

Instead of manually calculating the offset of the channels CCxE bit,
make use of the TIM_CCER_CCxE macro.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
 drivers/pwm/pwm-stm32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index ec2c05c9ee7a..c6625f51a199 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -88,7 +88,7 @@ static int stm32_pwm_round_waveform_tohw(struct pwm_chip *chip,
 
 	rate = clk_get_rate(priv->clk);
 
-	if (active_channels(priv) & ~(1 << ch * 4)) {
+	if (active_channels(priv) & ~TIM_CCER_CCxE(ch + 1)) {
 		u64 arr;
 
 		/*
-- 
2.47.2


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

* [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
                   ` (2 preceding siblings ...)
  2025-04-05  9:27 ` [PATCH 3/6] pwm: stm32: Don't open-code TIM_CCER_CCxE() Uwe Kleine-König
@ 2025-04-05  9:27 ` Uwe Kleine-König
  2025-04-05 22:15   ` kernel test robot
  2025-04-06  4:58   ` kernel test robot
  2025-04-05  9:27 ` [PATCH 5/6] pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up Uwe Kleine-König
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm
  Cc: Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue, linux-stm32,
	linux-arm-kernel, linux-kernel

When you're interested in the actual register settings the driver
chooses or interprets you want to see them also for calls that hit
corner cases.

Make sure that all calls to stm32_pwm_round_waveform_tohw() and
stm32_pwm_round_waveform_fromhw() emit the debug message about the
register settings.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
 drivers/pwm/pwm-stm32.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index c6625f51a199..dca5d09d80b9 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -180,11 +180,11 @@ static int stm32_pwm_round_waveform_tohw(struct pwm_chip *chip,
 
 	wfhw->ccr = min_t(u64, ccr, wfhw->arr + 1);
 
+out:
 	dev_dbg(&chip->dev, "pwm#%u: %lld/%lld [+%lld] @%lu -> CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x\n",
 		pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
 		rate, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr);
 
-out:
 	clk_disable(priv->clk);
 
 	return ret;
@@ -236,17 +236,16 @@ static int stm32_pwm_round_waveform_fromhw(struct pwm_chip *chip,
 			wf->duty_length_ns = ccr_ns;
 			wf->duty_offset_ns = 0;
 		}
-
-		dev_dbg(&chip->dev, "pwm#%u: CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x @%lu -> %lld/%lld [+%lld]\n",
-			pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
-			wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns);
-
 	} else {
 		*wf = (struct pwm_waveform){
 			.period_length_ns = 0,
 		};
 	}
 
+	dev_dbg(&chip->dev, "pwm#%u: CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x @%lu -> %lld/%lld [+%lld]\n",
+		pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
+		wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns);
+
 	return 0;
 }
 
-- 
2.47.2


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

* [PATCH 5/6] pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
                   ` (3 preceding siblings ...)
  2025-04-05  9:27 ` [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks Uwe Kleine-König
@ 2025-04-05  9:27 ` Uwe Kleine-König
  2025-04-07 12:52   ` Trevor Gamblin
  2025-04-05  9:27 ` [PATCH 6/6] pwm: Do stricter return value checking for .round_waveform_tohw() Uwe Kleine-König
  2025-04-07 10:24 ` [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
  6 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm; +Cc: Michael Hennerich, Nuno Sá, Trevor Gamblin, linux-kernel

The .round_waveform_tohw() is supposed to return 1 if the requested
waveform cannot be implemented by rounding down all parameters. Also
adapt the corresponding comment to better describe why the implemented
procedure is right.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
 drivers/pwm/pwm-axi-pwmgen.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-axi-pwmgen.c b/drivers/pwm/pwm-axi-pwmgen.c
index 4259a0db9ff4..4337c8f5acf0 100644
--- a/drivers/pwm/pwm-axi-pwmgen.c
+++ b/drivers/pwm/pwm-axi-pwmgen.c
@@ -75,6 +75,7 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip,
 {
 	struct axi_pwmgen_waveform *wfhw = _wfhw;
 	struct axi_pwmgen_ddata *ddata = axi_pwmgen_ddata_from_chip(chip);
+	int ret = 0;
 
 	if (wf->period_length_ns == 0) {
 		*wfhw = (struct axi_pwmgen_waveform){
@@ -91,12 +92,15 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip,
 		if (wfhw->period_cnt == 0) {
 			/*
 			 * The specified period is too short for the hardware.
-			 * Let's round .duty_cycle down to 0 to get a (somewhat)
-			 * valid result.
+			 * So round up .period_cnt to 1 (i.e. the smallest
+			 * possible period). With .duty_cycle and .duty_offset
+			 * being less than or equal to .period, their rounded
+			 * value must be 0.
 			 */
 			wfhw->period_cnt = 1;
 			wfhw->duty_cycle_cnt = 0;
 			wfhw->duty_offset_cnt = 0;
+			ret = 1;
 		} else {
 			wfhw->duty_cycle_cnt = min_t(u64,
 						     mul_u64_u32_div(wf->duty_length_ns, ddata->clk_rate_hz, NSEC_PER_SEC),
@@ -111,7 +115,7 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip,
 		pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
 		ddata->clk_rate_hz, wfhw->period_cnt, wfhw->duty_cycle_cnt, wfhw->duty_offset_cnt);
 
-	return 0;
+	return ret;
 }
 
 static int axi_pwmgen_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm,
-- 
2.47.2


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

* [PATCH 6/6] pwm: Do stricter return value checking for .round_waveform_tohw()
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
                   ` (4 preceding siblings ...)
  2025-04-05  9:27 ` [PATCH 5/6] pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up Uwe Kleine-König
@ 2025-04-05  9:27 ` Uwe Kleine-König
  2025-04-07 10:24 ` [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
  6 siblings, 0 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-05  9:27 UTC (permalink / raw)
  To: linux-pwm; +Cc: linux-kernel

The .round_waveform_tohw() is supposed to return 0 if the request could
be rounded down to match the hardware capabilities and return 1 if
rounding down wasn't possible.

Expand the PWM_DEBUG check to not only assert proper downrounding if 0
was returned but also check that it was actually rounded up when the
callback signalled uprounding.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
---
 drivers/pwm/core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 0387bd838487..1a9d497f5cfe 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -270,10 +270,10 @@ int pwm_round_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *
 			wf_req.duty_length_ns, wf_req.period_length_ns, wf_req.duty_offset_ns, ret_tohw);
 
 	if (IS_ENABLED(CONFIG_PWM_DEBUG) &&
-	    ret_tohw == 0 && !pwm_check_rounding(&wf_req, wf))
-		dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu]\n",
+	    (ret_tohw == 0) != pwm_check_rounding(&wf_req, wf))
+		dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu], ret: %d\n",
 			wf_req.duty_length_ns, wf_req.period_length_ns, wf_req.duty_offset_ns,
-			wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns);
+			wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns, ret_tohw);
 
 	return ret_tohw;
 }
@@ -341,10 +341,10 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
 		if (err)
 			return err;
 
-		if (IS_ENABLED(CONFIG_PWM_DEBUG) && ret_tohw == 0 && !pwm_check_rounding(wf, &wf_rounded))
-			dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu]\n",
+		if (IS_ENABLED(CONFIG_PWM_DEBUG) && (ret_tohw == 0) != pwm_check_rounding(wf, &wf_rounded))
+			dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu], ret: %d\n",
 				wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns,
-				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns);
+				wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns, ret_tohw);
 
 		if (exact && pwmwfcmp(wf, &wf_rounded)) {
 			dev_dbg(&chip->dev, "Requested no rounding, but %llu/%llu [+%llu] -> %llu/%llu [+%llu]\n",
-- 
2.47.2


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

* Re: [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks
  2025-04-05  9:27 ` [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks Uwe Kleine-König
@ 2025-04-05 22:15   ` kernel test robot
  2025-04-06  4:58   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-04-05 22:15 UTC (permalink / raw)
  To: Uwe Kleine-König, linux-pwm
  Cc: oe-kbuild-all, Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue,
	linux-stm32, linux-arm-kernel, linux-kernel

Hi Uwe,

kernel test robot noticed the following build errors:

[auto build test ERROR on e48e99b6edf41c69c5528aa7ffb2daf3c59ee105]

url:    https://github.com/intel-lab-lkp/linux/commits/Uwe-Kleine-K-nig/pwm-Let-pwm_set_waveform-succeed-even-if-lowlevel-driver-rounded-up/20250405-173024
base:   e48e99b6edf41c69c5528aa7ffb2daf3c59ee105
patch link:    https://lore.kernel.org/r/fe154e79319da5ff4159cdc71201a9d3b395e491.1743844730.git.u.kleine-koenig%40baylibre.com
patch subject: [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks
config: arm-randconfig-004-20250406 (https://download.01.org/0day-ci/archive/20250406/202504060517.dHXuUANs-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250406/202504060517.dHXuUANs-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504060517.dHXuUANs-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/linux/device.h:15,
                    from include/linux/dmaengine.h:8,
                    from include/linux/mfd/stm32-timers.h:11,
                    from drivers/pwm/pwm-stm32.c:12:
   drivers/pwm/pwm-stm32.c: In function 'stm32_pwm_round_waveform_fromhw':
>> drivers/pwm/pwm-stm32.c:246:60: error: 'rate' undeclared (first use in this function)
     246 |   pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
         |                                                            ^~~~
   include/linux/dev_printk.h:139:35: note: in definition of macro 'dev_no_printk'
     139 |    _dev_printk(level, dev, fmt, ##__VA_ARGS__); \
         |                                   ^~~~~~~~~~~
   drivers/pwm/pwm-stm32.c:245:2: note: in expansion of macro 'dev_dbg'
     245 |  dev_dbg(&chip->dev, "pwm#%u: CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x @%lu -> %lld/%lld [+%lld]\n",
         |  ^~~~~~~
   drivers/pwm/pwm-stm32.c:246:60: note: each undeclared identifier is reported only once for each function it appears in
     246 |   pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
         |                                                            ^~~~
   include/linux/dev_printk.h:139:35: note: in definition of macro 'dev_no_printk'
     139 |    _dev_printk(level, dev, fmt, ##__VA_ARGS__); \
         |                                   ^~~~~~~~~~~
   drivers/pwm/pwm-stm32.c:245:2: note: in expansion of macro 'dev_dbg'
     245 |  dev_dbg(&chip->dev, "pwm#%u: CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x @%lu -> %lld/%lld [+%lld]\n",
         |  ^~~~~~~


vim +/rate +246 drivers/pwm/pwm-stm32.c

   208	
   209	static int stm32_pwm_round_waveform_fromhw(struct pwm_chip *chip,
   210						   struct pwm_device *pwm,
   211						   const void *_wfhw,
   212						   struct pwm_waveform *wf)
   213	{
   214		const struct stm32_pwm_waveform *wfhw = _wfhw;
   215		struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
   216		unsigned int ch = pwm->hwpwm;
   217	
   218		if (wfhw->ccer & TIM_CCER_CCxE(ch + 1)) {
   219			unsigned long rate = clk_get_rate(priv->clk);
   220			u64 ccr_ns;
   221	
   222			/* The result doesn't overflow for rate >= 15259 */
   223			wf->period_length_ns = stm32_pwm_mul_u64_u64_div_u64_roundup(((u64)wfhw->psc + 1) * (wfhw->arr + 1),
   224										     NSEC_PER_SEC, rate);
   225	
   226			ccr_ns = stm32_pwm_mul_u64_u64_div_u64_roundup(((u64)wfhw->psc + 1) * wfhw->ccr,
   227								       NSEC_PER_SEC, rate);
   228	
   229			if (wfhw->ccer & TIM_CCER_CCxP(ch + 1)) {
   230				wf->duty_length_ns =
   231					stm32_pwm_mul_u64_u64_div_u64_roundup(((u64)wfhw->psc + 1) * (wfhw->arr + 1 - wfhw->ccr),
   232									      NSEC_PER_SEC, rate);
   233	
   234				wf->duty_offset_ns = ccr_ns;
   235			} else {
   236				wf->duty_length_ns = ccr_ns;
   237				wf->duty_offset_ns = 0;
   238			}
   239		} else {
   240			*wf = (struct pwm_waveform){
   241				.period_length_ns = 0,
   242			};
   243		}
   244	
   245		dev_dbg(&chip->dev, "pwm#%u: CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x @%lu -> %lld/%lld [+%lld]\n",
 > 246			pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
   247			wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns);
   248	
   249		return 0;
   250	}
   251	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks
  2025-04-05  9:27 ` [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks Uwe Kleine-König
  2025-04-05 22:15   ` kernel test robot
@ 2025-04-06  4:58   ` kernel test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-04-06  4:58 UTC (permalink / raw)
  To: Uwe Kleine-König, linux-pwm
  Cc: llvm, oe-kbuild-all, Fabrice Gasnier, Maxime Coquelin,
	Alexandre Torgue, linux-stm32, linux-arm-kernel, linux-kernel

Hi Uwe,

kernel test robot noticed the following build errors:

[auto build test ERROR on e48e99b6edf41c69c5528aa7ffb2daf3c59ee105]

url:    https://github.com/intel-lab-lkp/linux/commits/Uwe-Kleine-K-nig/pwm-Let-pwm_set_waveform-succeed-even-if-lowlevel-driver-rounded-up/20250405-173024
base:   e48e99b6edf41c69c5528aa7ffb2daf3c59ee105
patch link:    https://lore.kernel.org/r/fe154e79319da5ff4159cdc71201a9d3b395e491.1743844730.git.u.kleine-koenig%40baylibre.com
patch subject: [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks
config: x86_64-buildonly-randconfig-001-20250406 (https://download.01.org/0day-ci/archive/20250406/202504061207.97zbNPvV-lkp@intel.com/config)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250406/202504061207.97zbNPvV-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504061207.97zbNPvV-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/pwm/pwm-stm32.c:246:60: error: use of undeclared identifier 'rate'
     246 |                 pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
         |                                                                          ^
   1 error generated.


vim +/rate +246 drivers/pwm/pwm-stm32.c

   208	
   209	static int stm32_pwm_round_waveform_fromhw(struct pwm_chip *chip,
   210						   struct pwm_device *pwm,
   211						   const void *_wfhw,
   212						   struct pwm_waveform *wf)
   213	{
   214		const struct stm32_pwm_waveform *wfhw = _wfhw;
   215		struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
   216		unsigned int ch = pwm->hwpwm;
   217	
   218		if (wfhw->ccer & TIM_CCER_CCxE(ch + 1)) {
   219			unsigned long rate = clk_get_rate(priv->clk);
   220			u64 ccr_ns;
   221	
   222			/* The result doesn't overflow for rate >= 15259 */
   223			wf->period_length_ns = stm32_pwm_mul_u64_u64_div_u64_roundup(((u64)wfhw->psc + 1) * (wfhw->arr + 1),
   224										     NSEC_PER_SEC, rate);
   225	
   226			ccr_ns = stm32_pwm_mul_u64_u64_div_u64_roundup(((u64)wfhw->psc + 1) * wfhw->ccr,
   227								       NSEC_PER_SEC, rate);
   228	
   229			if (wfhw->ccer & TIM_CCER_CCxP(ch + 1)) {
   230				wf->duty_length_ns =
   231					stm32_pwm_mul_u64_u64_div_u64_roundup(((u64)wfhw->psc + 1) * (wfhw->arr + 1 - wfhw->ccr),
   232									      NSEC_PER_SEC, rate);
   233	
   234				wf->duty_offset_ns = ccr_ns;
   235			} else {
   236				wf->duty_length_ns = ccr_ns;
   237				wf->duty_offset_ns = 0;
   238			}
   239		} else {
   240			*wf = (struct pwm_waveform){
   241				.period_length_ns = 0,
   242			};
   243		}
   244	
   245		dev_dbg(&chip->dev, "pwm#%u: CCER: %08x, PSC: %08x, ARR: %08x, CCR: %08x @%lu -> %lld/%lld [+%lld]\n",
 > 246			pwm->hwpwm, wfhw->ccer, wfhw->psc, wfhw->arr, wfhw->ccr, rate,
   247			wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns);
   248	
   249		return 0;
   250	}
   251	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH 0/6] pwm: Some fixes preparing chardev support
  2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
                   ` (5 preceding siblings ...)
  2025-04-05  9:27 ` [PATCH 6/6] pwm: Do stricter return value checking for .round_waveform_tohw() Uwe Kleine-König
@ 2025-04-07 10:24 ` Uwe Kleine-König
  2025-04-07 15:16   ` Uwe Kleine-König
  6 siblings, 1 reply; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-07 10:24 UTC (permalink / raw)
  To: linux-pwm
  Cc: linux-kernel, Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue,
	linux-stm32, linux-arm-kernel, Michael Hennerich, Nuno Sá,
	Trevor Gamblin

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

On Sat, Apr 05, 2025 at 11:27:11AM +0200, Uwe Kleine-König wrote:
> Hello,
> 
> while working on character device support for PWMs I found a few
> inconsistencies that are fixed in this series. After that I plan to work
> on getting the character device support into shape to get it into
> mainline, too.
> 
> While some of these patches qualify as fixes I think there is no urge to
> get them into 6.15, but given there is a bunch of such changes I might
> send them to all together to Linus for inclusion to 6.15.
> 
> Best regards
> Uwe
> 
> Uwe Kleine-König (6):
>   pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
>   pwm: stm32: Search an appropriate duty_cycle if period cannot be
>     modified
>   pwm: stm32: Don't open-code TIM_CCER_CCxE()
>   pwm: stm32: Emit debug output also for corner cases of the rounding
>     callbacks
>   pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was
>     rounded up
>   pwm: Do stricter return value checking for .round_waveform_tohw()

I applied patches #1, #2 and #5 to
https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/fixes

I still havn't made up my mind about trying to get these into v6.15, but
at least they should be included in next for now.

Best regards
Uwe

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

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

* Re: [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
  2025-04-05  9:27 ` [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up Uwe Kleine-König
@ 2025-04-07 12:52   ` Trevor Gamblin
  0 siblings, 0 replies; 13+ messages in thread
From: Trevor Gamblin @ 2025-04-07 12:52 UTC (permalink / raw)
  To: Uwe Kleine-König, linux-pwm; +Cc: linux-kernel


On 2025-04-05 05:27, Uwe Kleine-König wrote:
> Waveform parameters are supposed to be rounded down to the next value
> possible for the hardware. However when a requested value is too small,
> .round_waveform_tohw() is supposed to pick the next bigger value and
> return 1. Let pwm_set_waveform() behave in the same way.
>
> This creates consistency between pwm_set_waveform_might_sleep() with
> exact=false and pwm_round_waveform_might_sleep() +
> pwm_set_waveform_might_sleep() with exact=true.
>
> The PWM_DEBUG rounding check has to be adapted to only trigger if no
> uprounding happend.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>

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

* Re: [PATCH 5/6] pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up
  2025-04-05  9:27 ` [PATCH 5/6] pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up Uwe Kleine-König
@ 2025-04-07 12:52   ` Trevor Gamblin
  0 siblings, 0 replies; 13+ messages in thread
From: Trevor Gamblin @ 2025-04-07 12:52 UTC (permalink / raw)
  To: Uwe Kleine-König, linux-pwm
  Cc: Michael Hennerich, Nuno Sá, linux-kernel


On 2025-04-05 05:27, Uwe Kleine-König wrote:
> The .round_waveform_tohw() is supposed to return 1 if the requested
> waveform cannot be implemented by rounding down all parameters. Also
> adapt the corresponding comment to better describe why the implemented
> procedure is right.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>

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

* Re: [PATCH 0/6] pwm: Some fixes preparing chardev support
  2025-04-07 10:24 ` [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
@ 2025-04-07 15:16   ` Uwe Kleine-König
  0 siblings, 0 replies; 13+ messages in thread
From: Uwe Kleine-König @ 2025-04-07 15:16 UTC (permalink / raw)
  To: linux-pwm
  Cc: linux-kernel, Fabrice Gasnier, Maxime Coquelin, Alexandre Torgue,
	linux-stm32, linux-arm-kernel, Michael Hennerich, Nuno Sá,
	Trevor Gamblin

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

On Mon, Apr 07, 2025 at 12:24:31PM +0200, Uwe Kleine-König wrote:
> On Sat, Apr 05, 2025 at 11:27:11AM +0200, Uwe Kleine-König wrote:
> > Hello,
> > 
> > while working on character device support for PWMs I found a few
> > inconsistencies that are fixed in this series. After that I plan to work
> > on getting the character device support into shape to get it into
> > mainline, too.
> > 
> > While some of these patches qualify as fixes I think there is no urge to
> > get them into 6.15, but given there is a bunch of such changes I might
> > send them to all together to Linus for inclusion to 6.15.
> > 
> > Best regards
> > Uwe
> > 
> > Uwe Kleine-König (6):
> >   pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
> >   pwm: stm32: Search an appropriate duty_cycle if period cannot be
> >     modified
> >   pwm: stm32: Don't open-code TIM_CCER_CCxE()
> >   pwm: stm32: Emit debug output also for corner cases of the rounding
> >     callbacks
> >   pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was
> >     rounded up
> >   pwm: Do stricter return value checking for .round_waveform_tohw()
> 
> I applied patches #1, #2 and #5 to
> https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/fixes

And patches #3, #4 and #6 applied to

https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next

with 

diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
index dca5d09d80b9..4b148f0afeb9 100644
--- a/drivers/pwm/pwm-stm32.c
+++ b/drivers/pwm/pwm-stm32.c
@@ -213,10 +213,10 @@ static int stm32_pwm_round_waveform_fromhw(struct pwm_chip *chip,
 {
 	const struct stm32_pwm_waveform *wfhw = _wfhw;
 	struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
+	unsigned long rate = clk_get_rate(priv->clk);
 	unsigned int ch = pwm->hwpwm;
 
 	if (wfhw->ccer & TIM_CCER_CCxE(ch + 1)) {
-		unsigned long rate = clk_get_rate(priv->clk);
 		u64 ccr_ns;
 
 		/* The result doesn't overflow for rate >= 15259 */

squashed into #4 to fix the build failure that the 0day robot reported
in this thread.

Best regards
Uwe

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

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

end of thread, other threads:[~2025-04-07 15:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-05  9:27 [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
2025-04-05  9:27 ` [PATCH 1/6] pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up Uwe Kleine-König
2025-04-07 12:52   ` Trevor Gamblin
2025-04-05  9:27 ` [PATCH 2/6] pwm: stm32: Search an appropriate duty_cycle if period cannot be modified Uwe Kleine-König
2025-04-05  9:27 ` [PATCH 3/6] pwm: stm32: Don't open-code TIM_CCER_CCxE() Uwe Kleine-König
2025-04-05  9:27 ` [PATCH 4/6] pwm: stm32: Emit debug output also for corner cases of the rounding callbacks Uwe Kleine-König
2025-04-05 22:15   ` kernel test robot
2025-04-06  4:58   ` kernel test robot
2025-04-05  9:27 ` [PATCH 5/6] pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up Uwe Kleine-König
2025-04-07 12:52   ` Trevor Gamblin
2025-04-05  9:27 ` [PATCH 6/6] pwm: Do stricter return value checking for .round_waveform_tohw() Uwe Kleine-König
2025-04-07 10:24 ` [PATCH 0/6] pwm: Some fixes preparing chardev support Uwe Kleine-König
2025-04-07 15:16   ` Uwe Kleine-König

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox