From 938fedbed2440dbdbc2cf7f10e0de86b0f832294 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Jul 2024 12:51:22 +0200 Subject: [PATCH] 6.9-stable patches added patches: pwm-stm32-fix-calculation-of-prescaler.patch pwm-stm32-fix-error-message-to-not-describe-the-previous-error-path.patch --- ...m-stm32-fix-calculation-of-prescaler.patch | 77 +++++++++++++++++++ ...not-describe-the-previous-error-path.patch | 39 ++++++++++ queue-6.9/series | 2 + 3 files changed, 118 insertions(+) create mode 100644 queue-6.9/pwm-stm32-fix-calculation-of-prescaler.patch create mode 100644 queue-6.9/pwm-stm32-fix-error-message-to-not-describe-the-previous-error-path.patch diff --git a/queue-6.9/pwm-stm32-fix-calculation-of-prescaler.patch b/queue-6.9/pwm-stm32-fix-calculation-of-prescaler.patch new file mode 100644 index 00000000000..bb2ef9671af --- /dev/null +++ b/queue-6.9/pwm-stm32-fix-calculation-of-prescaler.patch @@ -0,0 +1,77 @@ +From dab8f9f0fe3aada61c0eb013dcf7d3ff75a2c336 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Fri, 21 Jun 2024 16:37:13 +0200 +Subject: pwm: stm32: Fix calculation of prescaler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit dab8f9f0fe3aada61c0eb013dcf7d3ff75a2c336 upstream. + +A small prescaler is beneficial, as this improves the resolution of the +duty_cycle configuration. However if the prescaler is too small, the +maximal possible period becomes considerably smaller than the requested +value. + +One situation where this goes wrong is the following: With a parent +clock rate of 208877930 Hz and max_arr = 0xffff = 65535, a request for +period = 941243 ns currently results in PSC = 1. The value for ARR is +then calculated to + + ARR = 941243 * 208877930 / (1000000000 * 2) - 1 = 98301 + +This value is bigger than 65535 however and so doesn't fit into the +respective register field. In this particular case the PWM was +configured for a period of 313733.4806027616 ns (with ARR = 98301 & +0xffff). Even if ARR was configured to its maximal value, only period = +627495.6861167669 ns would be achievable. + +Fix the calculation accordingly and adapt the comment to match the new +algorithm. + +With the calculation fixed the above case results in PSC = 2 and so an +actual period of 941229.1667195285 ns. + +Fixes: 8002fbeef1e4 ("pwm: stm32: Calculate prescaler with a division instead of a loop") +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/b4d96b79917617434a540df45f20cb5de4142f88.1718979150.git.u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-stm32.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -321,17 +321,23 @@ static int stm32_pwm_config(struct stm32 + * First we need to find the minimal value for prescaler such that + * + * period_ns * clkrate +- * ------------------------------ ++ * ------------------------------ < max_arr + 1 + * NSEC_PER_SEC * (prescaler + 1) + * +- * isn't bigger than max_arr. ++ * This equation is equivalent to ++ * ++ * period_ns * clkrate ++ * ---------------------------- < prescaler + 1 ++ * NSEC_PER_SEC * (max_arr + 1) ++ * ++ * Using integer division and knowing that the right hand side is ++ * integer, this is further equivalent to ++ * ++ * (period_ns * clkrate) // (NSEC_PER_SEC * (max_arr + 1)) ≤ prescaler + */ + + prescaler = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk), +- (u64)NSEC_PER_SEC * priv->max_arr); +- if (prescaler > 0) +- prescaler -= 1; +- ++ (u64)NSEC_PER_SEC * ((u64)priv->max_arr + 1)); + if (prescaler > MAX_TIM_PSC) + return -EINVAL; + diff --git a/queue-6.9/pwm-stm32-fix-error-message-to-not-describe-the-previous-error-path.patch b/queue-6.9/pwm-stm32-fix-error-message-to-not-describe-the-previous-error-path.patch new file mode 100644 index 00000000000..c7c12e6f97d --- /dev/null +++ b/queue-6.9/pwm-stm32-fix-error-message-to-not-describe-the-previous-error-path.patch @@ -0,0 +1,39 @@ +From f01af3022d4a46362c5dda3d35dea939f3246d10 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= +Date: Fri, 21 Jun 2024 16:37:14 +0200 +Subject: pwm: stm32: Fix error message to not describe the previous error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +commit f01af3022d4a46362c5dda3d35dea939f3246d10 upstream. + +"Failed to lock the clock" is an appropriate error message for +clk_rate_exclusive_get() failing, but not for the clock running too +fast for the driver's calculations. + +Adapt the error message accordingly. + +Fixes: d44d635635a7 ("pwm: stm32: Fix for settings using period > UINT32_MAX") +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/285182163211203fc823a65b180761f46e828dcb.1718979150.git.u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-stm32.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pwm/pwm-stm32.c ++++ b/drivers/pwm/pwm-stm32.c +@@ -679,7 +679,8 @@ static int stm32_pwm_probe(struct platfo + * .apply() won't overflow. + */ + if (clk_get_rate(priv->clk) > 1000000000) +- return dev_err_probe(dev, -EINVAL, "Failed to lock clock\n"); ++ return dev_err_probe(dev, -EINVAL, "Clock freq too high (%lu)\n", ++ clk_get_rate(priv->clk)); + + chip->ops = &stm32pwm_ops; + diff --git a/queue-6.9/series b/queue-6.9/series index b96f2c62bee..f7012521fc6 100644 --- a/queue-6.9/series +++ b/queue-6.9/series @@ -200,3 +200,5 @@ bcachefs-fix-setting-of-downgrade-recovery-passes-errors.patch bcachefs-btree_gc-can-now-handle-unknown-btrees.patch revert-net-sfp-enhance-quirk-for-fibrestore-2.5g-copper-sfp-module.patch mm-page_alloc-separate-thp-pcp-into-movable-and-non-movable-categories.patch +pwm-stm32-fix-calculation-of-prescaler.patch +pwm-stm32-fix-error-message-to-not-describe-the-previous-error-path.patch -- 2.47.3