]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.9
authorSasha Levin <sashal@kernel.org>
Thu, 27 Jun 2024 18:51:37 +0000 (14:51 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 27 Jun 2024 18:51:37 +0000 (14:51 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.9/mips-pci-lantiq-restore-reset-gpio-polarity.patch [new file with mode: 0644]
queue-6.9/pwm-stm32-calculate-prescaler-with-a-division-instea.patch [new file with mode: 0644]
queue-6.9/pwm-stm32-fix-for-settings-using-period-uint32_max.patch [new file with mode: 0644]
queue-6.9/pwm-stm32-improve-precision-of-calculation-in-.apply.patch [new file with mode: 0644]
queue-6.9/pwm-stm32-refuse-too-small-period-requests.patch [new file with mode: 0644]
queue-6.9/series

diff --git a/queue-6.9/mips-pci-lantiq-restore-reset-gpio-polarity.patch b/queue-6.9/mips-pci-lantiq-restore-reset-gpio-polarity.patch
new file mode 100644 (file)
index 0000000..61f6149
--- /dev/null
@@ -0,0 +1,73 @@
+From 88411c94960d96e1e1c379f9fe0e8f637c0b9a00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jun 2024 11:04:00 +0200
+Subject: MIPS: pci: lantiq: restore reset gpio polarity
+
+From: Martin Schiller <ms@dev.tdt.de>
+
+[ Upstream commit 277a0363120276645ae598d8d5fea7265e076ae9 ]
+
+Commit 90c2d2eb7ab5 ("MIPS: pci: lantiq: switch to using gpiod API") not
+only switched to the gpiod API, but also inverted / changed the polarity
+of the GPIO.
+
+According to the PCI specification, the RST# pin is an active-low
+signal. However, most of the device trees that have been widely used for
+a long time (mainly in the openWrt project) define this GPIO as
+active-high and the old driver code inverted the signal internally.
+
+Apparently there are actually boards where the reset gpio must be
+operated inverted. For this reason, we cannot use the GPIOD_OUT_LOW/HIGH
+flag for initialization. Instead, we must explicitly set the gpio to
+value 1 in order to take into account any "GPIO_ACTIVE_LOW" flag that
+may have been set.
+
+In order to remain compatible with all these existing device trees, we
+should therefore keep the logic as it was before the commit.
+
+Fixes: 90c2d2eb7ab5 ("MIPS: pci: lantiq: switch to using gpiod API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin Schiller <ms@dev.tdt.de>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/pci/pci-lantiq.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c
+index 68a8cefed420b..0844db34022e4 100644
+--- a/arch/mips/pci/pci-lantiq.c
++++ b/arch/mips/pci/pci-lantiq.c
+@@ -124,14 +124,14 @@ static int ltq_pci_startup(struct platform_device *pdev)
+               clk_disable(clk_external);
+       /* setup reset gpio used by pci */
+-      reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
+-                                           GPIOD_OUT_LOW);
++      reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_ASIS);
+       error = PTR_ERR_OR_ZERO(reset_gpio);
+       if (error) {
+               dev_err(&pdev->dev, "failed to request gpio: %d\n", error);
+               return error;
+       }
+       gpiod_set_consumer_name(reset_gpio, "pci_reset");
++      gpiod_direction_output(reset_gpio, 1);
+       /* enable auto-switching between PCI and EBU */
+       ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
+@@ -194,10 +194,10 @@ static int ltq_pci_startup(struct platform_device *pdev)
+       /* toggle reset pin */
+       if (reset_gpio) {
+-              gpiod_set_value_cansleep(reset_gpio, 1);
++              gpiod_set_value_cansleep(reset_gpio, 0);
+               wmb();
+               mdelay(1);
+-              gpiod_set_value_cansleep(reset_gpio, 0);
++              gpiod_set_value_cansleep(reset_gpio, 1);
+       }
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.9/pwm-stm32-calculate-prescaler-with-a-division-instea.patch b/queue-6.9/pwm-stm32-calculate-prescaler-with-a-division-instea.patch
new file mode 100644 (file)
index 0000000..d628dc9
--- /dev/null
@@ -0,0 +1,77 @@
+From 44ca2eb625f4693b99d63a97bd906660d3bc16b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Mar 2024 22:52:16 +0100
+Subject: pwm: stm32: Calculate prescaler with a division instead of a loop
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 8002fbeef1e469b2c397d5cd2940e37b32a17849 ]
+
+Instead of looping over increasing values for the prescaler and testing
+if it's big enough, calculate the value using a single division.
+
+Link: https://lore.kernel.org/r/498a44b313a6c0a84ccddd03cd67aadaaaf7daf2.1710711976.git.u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Stable-dep-of: c45fcf46ca23 ("pwm: stm32: Refuse too small period requests")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-stm32.c | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
+index 27fcc90504f67..1c8911353b81d 100644
+--- a/drivers/pwm/pwm-stm32.c
++++ b/drivers/pwm/pwm-stm32.c
+@@ -311,29 +311,33 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
+ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch,
+                           u64 duty_ns, u64 period_ns)
+ {
+-      unsigned long long prd, div, dty;
+-      unsigned int prescaler = 0;
++      unsigned long long prd, dty;
++      unsigned long long prescaler;
+       u32 ccmr, mask, shift;
+       /*
+        * .probe() asserted that clk_get_rate() is not bigger than 1 GHz, so
+-       * this won't overflow.
++       * the calculations here won't overflow.
++       * First we need to find the minimal value for prescaler such that
++       *
++       *        period_ns * clkrate
++       *   ------------------------------
++       *   NSEC_PER_SEC * (prescaler + 1)
++       *
++       * isn't bigger than max_arr.
+        */
+-      div = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk),
+-                                NSEC_PER_SEC);
+-      prd = div;
+-
+-      while (div > priv->max_arr) {
+-              prescaler++;
+-              div = prd;
+-              do_div(div, prescaler + 1);
+-      }
+-      prd = div;
++      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;
+       if (prescaler > MAX_TIM_PSC)
+               return -EINVAL;
++      prd = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk),
++                                (u64)NSEC_PER_SEC * (prescaler + 1));
++
+       /*
+        * All channels share the same prescaler and counter so when two
+        * channels are active at the same time we can't change them
+-- 
+2.43.0
+
diff --git a/queue-6.9/pwm-stm32-fix-for-settings-using-period-uint32_max.patch b/queue-6.9/pwm-stm32-fix-for-settings-using-period-uint32_max.patch
new file mode 100644 (file)
index 0000000..ff9830a
--- /dev/null
@@ -0,0 +1,89 @@
+From 00fb789a41beba8c6654a8b319ab479d9263bb53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Mar 2024 22:52:15 +0100
+Subject: pwm: stm32: Fix for settings using period > UINT32_MAX
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit d44d635635a7192c773a75e674a8590a163e879e ]
+
+stm32_pwm_config() took the duty_cycle and period values with the type
+int, however stm32_pwm_apply() passed u64 values there. Expand the
+function parameters to u64 to not discard relevant bits and adapt the
+calculations to the wider type.
+
+To ensure the calculations won't overflow, check in .probe() the input
+clk doesn't run faster than 1 GHz.
+
+Link: https://lore.kernel.org/r/06b4a650a608d0887d934c1b2b8919e0f78e4db2.1710711976.git.u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Stable-dep-of: c45fcf46ca23 ("pwm: stm32: Refuse too small period requests")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-stm32.c | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
+index d50194ad24b1c..27fcc90504f67 100644
+--- a/drivers/pwm/pwm-stm32.c
++++ b/drivers/pwm/pwm-stm32.c
+@@ -309,16 +309,18 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
+ }
+ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch,
+-                          int duty_ns, int period_ns)
++                          u64 duty_ns, u64 period_ns)
+ {
+       unsigned long long prd, div, dty;
+       unsigned int prescaler = 0;
+       u32 ccmr, mask, shift;
+-      /* Period and prescaler values depends on clock rate */
+-      div = (unsigned long long)clk_get_rate(priv->clk) * period_ns;
+-
+-      do_div(div, NSEC_PER_SEC);
++      /*
++       * .probe() asserted that clk_get_rate() is not bigger than 1 GHz, so
++       * this won't overflow.
++       */
++      div = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk),
++                                NSEC_PER_SEC);
+       prd = div;
+       while (div > priv->max_arr) {
+@@ -351,9 +353,8 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch,
+       regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
+       /* Calculate the duty cycles */
+-      dty = (unsigned long long)clk_get_rate(priv->clk) * duty_ns;
+-      do_div(dty, prescaler + 1);
+-      do_div(dty, NSEC_PER_SEC);
++      dty = mul_u64_u64_div_u64(duty_ns, clk_get_rate(priv->clk),
++                                (u64)NSEC_PER_SEC * (prescaler + 1));
+       regmap_write(priv->regmap, TIM_CCR1 + 4 * ch, dty);
+@@ -657,6 +658,17 @@ static int stm32_pwm_probe(struct platform_device *pdev)
+       stm32_pwm_detect_complementary(priv);
++      ret = devm_clk_rate_exclusive_get(dev, priv->clk);
++      if (ret)
++              return dev_err_probe(dev, ret, "Failed to lock clock\n");
++
++      /*
++       * With the clk running with not more than 1 GHz the calculations in
++       * .apply() won't overflow.
++       */
++      if (clk_get_rate(priv->clk) > 1000000000)
++              return dev_err_probe(dev, -EINVAL, "Failed to lock clock\n");
++
+       chip->ops = &stm32pwm_ops;
+       /* Initialize clock refcount to number of enabled PWM channels. */
+-- 
+2.43.0
+
diff --git a/queue-6.9/pwm-stm32-improve-precision-of-calculation-in-.apply.patch b/queue-6.9/pwm-stm32-improve-precision-of-calculation-in-.apply.patch
new file mode 100644 (file)
index 0000000..22dd456
--- /dev/null
@@ -0,0 +1,64 @@
+From e910bcd4d018e3f4b0f49efd8e10b11703b5ef58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Mar 2024 22:52:14 +0100
+Subject: pwm: stm32: Improve precision of calculation in .apply()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit e419617847b688799a91126eb6c94b936bfb35ff ]
+
+While mathematically it's ok to calculate the number of cyles for the
+duty cycle as:
+
+       duty_cycles = period_cycles * duty_ns / period_ns
+
+this doesn't always give the right result when doing integer math. This
+is best demonstrated using an example: With the input clock running at
+208877930 Hz a request for duty_cycle = 383 ns and period = 49996 ns
+results in
+
+       period_cycles = clkrate * period_ns / NSEC_PER_SEC = 10443.06098828
+
+Now calculating duty_cycles with the above formula gives:
+
+       duty_cycles = 10443.06098828 * 383 / 49996 = 80.00024719
+
+However with period_cycle truncated to an integer results in:
+
+       duty_cycles = 10443 * 383 / 49996 = 79.99977998239859
+
+So while a value of (a little more than) 80 would be the right result,
+only 79 is used here. The problem here is that 14443 is a rounded result
+that should better not be used to do further math. So to fix that use
+the exact formular similar to how period_cycles is calculated.
+
+Link: https://lore.kernel.org/r/7628ecd8a7538aa5a7397f0fc4199a077168e8a6.1710711976.git.u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Stable-dep-of: c45fcf46ca23 ("pwm: stm32: Refuse too small period requests")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-stm32.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
+index 0c028d17c0752..d50194ad24b1c 100644
+--- a/drivers/pwm/pwm-stm32.c
++++ b/drivers/pwm/pwm-stm32.c
+@@ -351,8 +351,9 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch,
+       regmap_set_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE);
+       /* Calculate the duty cycles */
+-      dty = prd * duty_ns;
+-      do_div(dty, period_ns);
++      dty = (unsigned long long)clk_get_rate(priv->clk) * duty_ns;
++      do_div(dty, prescaler + 1);
++      do_div(dty, NSEC_PER_SEC);
+       regmap_write(priv->regmap, TIM_CCR1 + 4 * ch, dty);
+-- 
+2.43.0
+
diff --git a/queue-6.9/pwm-stm32-refuse-too-small-period-requests.patch b/queue-6.9/pwm-stm32-refuse-too-small-period-requests.patch
new file mode 100644 (file)
index 0000000..e3dbf8a
--- /dev/null
@@ -0,0 +1,46 @@
+From cdf1762592f778dbfec99a8f9c9cc6740b4ffc94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jun 2024 16:37:12 +0200
+Subject: pwm: stm32: Refuse too small period requests
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+
+[ Upstream commit c45fcf46ca2368dafe7e5c513a711a6f0f974308 ]
+
+If period_ns is small, prd might well become 0. Catch that case because
+otherwise with
+
+       regmap_write(priv->regmap, TIM_ARR, prd - 1);
+
+a few lines down quite a big period is configured.
+
+Fixes: 7edf7369205b ("pwm: Add driver for STM32 plaftorm")
+Cc: stable@vger.kernel.org
+Reviewed-by: Trevor Gamblin <tgamblin@baylibre.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
+Link: https://lore.kernel.org/r/b86f62f099983646f97eeb6bfc0117bb2d0c340d.1718979150.git.u.kleine-koenig@baylibre.com
+Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-stm32.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c
+index 1c8911353b81d..a8a1075f932df 100644
+--- a/drivers/pwm/pwm-stm32.c
++++ b/drivers/pwm/pwm-stm32.c
+@@ -337,6 +337,8 @@ static int stm32_pwm_config(struct stm32_pwm *priv, unsigned int ch,
+       prd = mul_u64_u64_div_u64(period_ns, clk_get_rate(priv->clk),
+                                 (u64)NSEC_PER_SEC * (prescaler + 1));
++      if (!prd)
++              return -EINVAL;
+       /*
+        * All channels share the same prescaler and counter so when two
+-- 
+2.43.0
+
index 6ac918fd0395591d75a03e3fe929584ac18feae1..932a2a6d3c3b992d978caadaac7a06e19f11a953 100644 (file)
@@ -7,3 +7,8 @@ pinctrl-rockchip-fix-pinmux-bits-for-rk3328-gpio2-b-.patch
 pinctrl-rockchip-fix-pinmux-bits-for-rk3328-gpio3-b-.patch
 pinctrl-rockchip-use-dedicated-pinctrl-type-for-rk33.patch
 pinctrl-rockchip-fix-pinmux-reset-in-rockchip_pmx_se.patch
+mips-pci-lantiq-restore-reset-gpio-polarity.patch
+pwm-stm32-improve-precision-of-calculation-in-.apply.patch
+pwm-stm32-fix-for-settings-using-period-uint32_max.patch
+pwm-stm32-calculate-prescaler-with-a-division-instea.patch
+pwm-stm32-refuse-too-small-period-requests.patch