* [PATCH 1/8] pwm: tegra: Prevent 32-bit period truncation and division by zero
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 15:46 ` Uwe Kleine-König
2026-11-05 14:38 ` [PATCH 2/8] pwm: mxs: Return early when disabling and fix error-path clock leak Lee Jones
` (6 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Thierry Reding, Uwe Kleine-König, Jonathan Hunter,
Mikko Perttunen, Sascha Hauer, Sandipan Patra, linux-pwm,
linux-tegra, linux-kernel
Cc: stable
tegra_pwm_apply() passes the 64-bit state->duty_cycle and state->period
values into tegra_pwm_config(), which accepts signed 32-bit int
parameters and performs DIV_ROUND_CLOSEST_ULL(c, period_ns) before
validating period_ns against pc->min_period_ns. If a consumer requests
a period that is a non-zero multiple of 2^32 nanoseconds, period_ns
truncates to zero and triggers a divide-by-zero panic.
Widen duty_ns and period_ns to u64 and validate that period_ns lies
within [pc->min_period_ns, U32_MAX] prior to dividing by period_ns.
Fixes: 1d7796bdb63a ("pwm: tegra: Support dynamic clock frequency configuration")
Fixes: fd3ddd4355c0 ("pwm: tegra: Implement .apply() callback")
Closes: https://sashiko.dev/#/bug/linux-5c5b97d6-4da6-4d06-9dc7-957419dcd832
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-tegra.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 5cdbe120ba2d..f99ae2b3a276 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -138,7 +138,7 @@ static inline void tegra_pwm_writel(struct pwm_device *pwm, unsigned int offset,
}
static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
- int duty_ns, int period_ns)
+ u64 duty_ns, u64 period_ns)
{
struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
unsigned long long c = duty_ns;
@@ -146,6 +146,12 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u32 val = 0;
int err;
+ /*
+ * min period = max clock limit / TEGRA_PWM_DEPTH
+ */
+ if (period_ns < pc->min_period_ns || period_ns > U32_MAX)
+ return -EINVAL;
+
/*
* Convert from duty_ns / period_ns to a fixed number of duty ticks
* per TEGRA_PWM_DEPTH cycles and make sure to round to the
@@ -156,12 +162,6 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
val = (u32)c << TEGRA_PWM_DUTY_SHIFT;
- /*
- * min period = max clock limit / TEGRA_PWM_DEPTH
- */
- if (period_ns < pc->min_period_ns)
- return -EINVAL;
-
/*
* Compute the prescaler value for which TEGRA_PWM_DEPTH
* cycles at the PWM clock rate will take period_ns nanoseconds.
Cc: Sandipan Patra <spatra@nvidia.com>
Cc: "Uwe Kleine-König" <ukleinek@kernel.org>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 1/8] pwm: tegra: Prevent 32-bit period truncation and division by zero
2026-11-05 14:38 ` [PATCH 1/8] pwm: tegra: Prevent 32-bit period truncation and division by zero Lee Jones
@ 2026-11-05 15:46 ` Uwe Kleine-König
0 siblings, 0 replies; 14+ messages in thread
From: Uwe Kleine-König @ 2026-11-05 15:46 UTC (permalink / raw)
To: Lee Jones
Cc: Thierry Reding, Jonathan Hunter, Mikko Perttunen, Sascha Hauer,
Sandipan Patra, linux-pwm, linux-tegra, linux-kernel, stable
[-- Attachment #1: Type: text/plain, Size: 1106 bytes --]
Hello Lee,
On Thu, Nov 05, 2026 at 02:38:03PM +0000, Lee Jones wrote:
> tegra_pwm_apply() passes the 64-bit state->duty_cycle and state->period
> values into tegra_pwm_config(), which accepts signed 32-bit int
> parameters and performs DIV_ROUND_CLOSEST_ULL(c, period_ns) before
> validating period_ns against pc->min_period_ns. If a consumer requests
> a period that is a non-zero multiple of 2^32 nanoseconds, period_ns
> truncates to zero and triggers a divide-by-zero panic.
>
> Widen duty_ns and period_ns to u64 and validate that period_ns lies
> within [pc->min_period_ns, U32_MAX] prior to dividing by period_ns.
>
> Fixes: 1d7796bdb63a ("pwm: tegra: Support dynamic clock frequency configuration")
> Fixes: fd3ddd4355c0 ("pwm: tegra: Implement .apply() callback")
> Closes: https://sashiko.dev/#/bug/linux-5c5b97d6-4da6-4d06-9dc7-957419dcd832
> Cc: stable@vger.kernel.org
> Signed-off-by: Lee Jones <lee@kernel.org>
This is already addressed in
9ad5602d4943 ("pwm: tegra: Fix value discarding for duty and period")
which is next-20261102 and later.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/8] pwm: mxs: Return early when disabling and fix error-path clock leak
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
2026-11-05 14:38 ` [PATCH 1/8] pwm: tegra: Prevent 32-bit period truncation and division by zero Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 16:50 ` Frank Li
2026-11-05 14:38 ` [PATCH 3/8] pwm: loongson: Fix 32-bit control register truncation in pwm_loongson_set_polarity() Lee Jones
` (5 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Uwe Kleine-König, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Shawn Guo, Thierry Reding,
Rasmus Villemoes, linux-pwm, imx, linux-arm-kernel, linux-kernel
Cc: stable
When disabling a PWM channel (!state->enabled), the PWM core permits
state->period to be zero. mxs_pwm_apply() currently falls through into
the period and duty-cycle calculations even when !state->enabled,
causing do_div(c, state->period) to divide by zero when state->period is
zero. In addition, if the requested period exceeds the maximum divider
(div >= PERIOD_CDIV_MAX) while the PWM channel is currently disabled,
mxs_pwm_apply() returns -EINVAL without disabling and unpreparing
mxs->clk.
Handle the !state->enabled path upfront and return early, and balance
clk_prepare_enable() on the -EINVAL error path.
Fixes: bf29c2ff82fd ("pwm: mxs: Implement ->apply()")
Closes: https://sashiko.dev/#/bug/linux-710f863f-6964-4e4f-990a-e5043dbc1a87
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-mxs.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c
index e1a3df6549fc..16233764fd3c 100644
--- a/drivers/pwm/pwm-mxs.c
+++ b/drivers/pwm/pwm-mxs.c
@@ -56,6 +56,14 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
unsigned long long c;
unsigned int pol_bits;
+ if (!state->enabled) {
+ if (pwm_is_enabled(pwm)) {
+ writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);
+ clk_disable_unprepare(mxs->clk);
+ }
+ return 0;
+ }
+
/*
* If the PWM channel is disabled, make sure to turn on the
* clock before calling clk_get_rate() and writing to the
@@ -67,9 +75,6 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret;
}
- if (!state->enabled && pwm_is_enabled(pwm))
- writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);
-
rate = clk_get_rate(mxs->clk);
while (1) {
c = rate >> cdiv_shift[div];
@@ -78,8 +83,11 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (c < PERIOD_PERIOD_MAX)
break;
div++;
- if (div >= PERIOD_CDIV_MAX)
+ if (div >= PERIOD_CDIV_MAX) {
+ if (!pwm_is_enabled(pwm))
+ clk_disable_unprepare(mxs->clk);
return -EINVAL;
+ }
}
period_cycles = c;
@@ -101,16 +109,12 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
writel(PERIOD_PERIOD(period_cycles) | pol_bits | PERIOD_CDIV(div),
mxs->base + PWM_PERIOD0 + pwm->hwpwm * 0x20);
- if (state->enabled) {
- if (!pwm_is_enabled(pwm)) {
- /*
- * The clock was enabled above. Just enable
- * the channel in the control register.
- */
- writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);
- }
- } else {
- clk_disable_unprepare(mxs->clk);
+ if (!pwm_is_enabled(pwm)) {
+ /*
+ * The clock was enabled above. Just enable
+ * the channel in the control register.
+ */
+ writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);
}
return 0;
}
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 2/8] pwm: mxs: Return early when disabling and fix error-path clock leak
2026-11-05 14:38 ` [PATCH 2/8] pwm: mxs: Return early when disabling and fix error-path clock leak Lee Jones
@ 2026-11-05 16:50 ` Frank Li
0 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2026-11-05 16:50 UTC (permalink / raw)
To: Lee Jones
Cc: Uwe Kleine-König, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Shawn Guo, Thierry Reding,
Rasmus Villemoes, linux-pwm, imx, linux-arm-kernel, linux-kernel,
stable
On Thu, Nov 05, 2026 at 02:38:04PM +0000, Lee Jones wrote:
> When disabling a PWM channel (!state->enabled), the PWM core permits
> state->period to be zero. mxs_pwm_apply() currently falls through into
> the period and duty-cycle calculations even when !state->enabled,
> causing do_div(c, state->period) to divide by zero when state->period is
> zero. In addition, if the requested period exceeds the maximum divider
> (div >= PERIOD_CDIV_MAX) while the PWM channel is currently disabled,
> mxs_pwm_apply() returns -EINVAL without disabling and unpreparing
> mxs->clk.
>
> Handle the !state->enabled path upfront and return early, and balance
> clk_prepare_enable() on the -EINVAL error path.
>
> Fixes: bf29c2ff82fd ("pwm: mxs: Implement ->apply()")
> Closes: https://sashiko.dev/#/bug/linux-710f863f-6964-4e4f-990a-e5043dbc1a87
> Cc: stable@vger.kernel.org
> Signed-off-by: Lee Jones <lee@kernel.org>
> --
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/pwm/pwm-mxs.c | 32 ++++++++++++++++++--------------
> 1 file changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c
> index e1a3df6549fc..16233764fd3c 100644
> --- a/drivers/pwm/pwm-mxs.c
> +++ b/drivers/pwm/pwm-mxs.c
> @@ -56,6 +56,14 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> unsigned long long c;
> unsigned int pol_bits;
>
> + if (!state->enabled) {
> + if (pwm_is_enabled(pwm)) {
> + writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);
> + clk_disable_unprepare(mxs->clk);
> + }
> + return 0;
> + }
> +
> /*
> * If the PWM channel is disabled, make sure to turn on the
> * clock before calling clk_get_rate() and writing to the
> @@ -67,9 +75,6 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> return ret;
> }
>
> - if (!state->enabled && pwm_is_enabled(pwm))
> - writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);
> -
> rate = clk_get_rate(mxs->clk);
> while (1) {
> c = rate >> cdiv_shift[div];
> @@ -78,8 +83,11 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> if (c < PERIOD_PERIOD_MAX)
> break;
> div++;
> - if (div >= PERIOD_CDIV_MAX)
> + if (div >= PERIOD_CDIV_MAX) {
> + if (!pwm_is_enabled(pwm))
> + clk_disable_unprepare(mxs->clk);
> return -EINVAL;
> + }
> }
>
> period_cycles = c;
> @@ -101,16 +109,12 @@ static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> writel(PERIOD_PERIOD(period_cycles) | pol_bits | PERIOD_CDIV(div),
> mxs->base + PWM_PERIOD0 + pwm->hwpwm * 0x20);
>
> - if (state->enabled) {
> - if (!pwm_is_enabled(pwm)) {
> - /*
> - * The clock was enabled above. Just enable
> - * the channel in the control register.
> - */
> - writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);
> - }
> - } else {
> - clk_disable_unprepare(mxs->clk);
> + if (!pwm_is_enabled(pwm)) {
> + /*
> + * The clock was enabled above. Just enable
> + * the channel in the control register.
> + */
> + writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);
> }
> return 0;
> }
> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> --
> 2.56.0.398.g882cbad275-goog
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/8] pwm: loongson: Fix 32-bit control register truncation in pwm_loongson_set_polarity()
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
2026-11-05 14:38 ` [PATCH 1/8] pwm: tegra: Prevent 32-bit period truncation and division by zero Lee Jones
2026-11-05 14:38 ` [PATCH 2/8] pwm: mxs: Return early when disabling and fix error-path clock leak Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 14:38 ` [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe() Lee Jones
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Binbin Zhou, Uwe Kleine-König, Juxin Gao, Huacai Chen,
linux-pwm, linux-kernel
Cc: stable
pwm_loongson_set_polarity() stores the 32-bit value read from
LOONGSON_PWM_REG_CTRL into a 16-bit local variable before writing it
back to the register, silently clearing the upper 16 bits.
Change val from u16 to u32 to match the 32-bit register width used
throughout the rest of the driver.
Fixes: 2b62c89448dd ("pwm: Add Loongson PWM controller support")
Closes: https://sashiko.dev/#/bug/linux-bea00bdd-ae27-4d81-9902-e96ed8b6d8ad
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-loongson.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c
index 98c809bde2b3..4e8b54c8016c 100644
--- a/drivers/pwm/pwm-loongson.c
+++ b/drivers/pwm/pwm-loongson.c
@@ -76,7 +76,7 @@ static inline void pwm_loongson_writel(struct pwm_loongson_ddata *ddata,
static int pwm_loongson_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
enum pwm_polarity polarity)
{
- u16 val;
+ u32 val;
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL);
Cc: Binbin Zhou <zhoubinbin@loongson.cn>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe()
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
` (2 preceding siblings ...)
2026-11-05 14:38 ` [PATCH 3/8] pwm: loongson: Fix 32-bit control register truncation in pwm_loongson_set_polarity() Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 15:48 ` Uwe Kleine-König
2026-11-05 14:38 ` [PATCH 5/8] pwm: fsl-ftm: Enable ipg_clk around regcache_sync() during resume Lee Jones
` (3 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Michael Hennerich, Nuno Sá, Trevor Gamblin,
Uwe Kleine-König, Sergiu Cuciurean, Drew Fustini, linux-pwm,
linux-kernel
Cc: stable
axi_pwmgen_probe() calls axi_pwmgen_setup(), which reads and writes MMIO
registers to verify the IP core version and determine the channel count,
before acquiring and enabling axi_clk. If the bootloader leaves the AXI
peripheral clock gated, accessing the registers causes an unclocked bus
access fault.
Acquire and enable the clocks before calling axi_pwmgen_setup().
Fixes: 41814fe5c782 ("pwm: Add driver for AXI PWM generator")
Closes: https://sashiko.dev/#/bug/linux-bc988dbc-7b12-4785-a164-b6dcab29b86a
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-axi-pwmgen.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/pwm/pwm-axi-pwmgen.c b/drivers/pwm/pwm-axi-pwmgen.c
index b40522f01002..7c1b38124787 100644
--- a/drivers/pwm/pwm-axi-pwmgen.c
+++ b/drivers/pwm/pwm-axi-pwmgen.c
@@ -270,16 +270,6 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(regmap),
"failed to init register map\n");
- ret = axi_pwmgen_setup(regmap, dev);
- if (ret < 0)
- return ret;
-
- chip = devm_pwmchip_alloc(dev, ret, sizeof(*ddata));
- if (IS_ERR(chip))
- return PTR_ERR(chip);
- ddata = pwmchip_get_drvdata(chip);
- ddata->regmap = regmap;
-
/*
* Using NULL here instead of "axi" for backwards compatibility. There
* are some dtbs that don't give clock-names and have the "ext" clock
@@ -305,6 +295,16 @@ static int axi_pwmgen_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to get exclusive rate\n");
+ ret = axi_pwmgen_setup(regmap, dev);
+ if (ret < 0)
+ return ret;
+
+ chip = devm_pwmchip_alloc(dev, ret, sizeof(*ddata));
+ if (IS_ERR(chip))
+ return PTR_ERR(chip);
+ ddata = pwmchip_get_drvdata(chip);
+ ddata->regmap = regmap;
+
ddata->clk_rate_hz = clk_get_rate(clk);
if (!ddata->clk_rate_hz || ddata->clk_rate_hz > NSEC_PER_SEC)
return dev_err_probe(dev, -EINVAL,
Cc: Drew Fustini <dfustini@baylibre.com>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe()
2026-11-05 14:38 ` [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe() Lee Jones
@ 2026-11-05 15:48 ` Uwe Kleine-König
2026-11-05 18:26 ` Lee Jones
0 siblings, 1 reply; 14+ messages in thread
From: Uwe Kleine-König @ 2026-11-05 15:48 UTC (permalink / raw)
To: Lee Jones
Cc: Michael Hennerich, Nuno Sá, Trevor Gamblin, Sergiu Cuciurean,
Drew Fustini, linux-pwm, linux-kernel, stable
[-- Attachment #1: Type: text/plain, Size: 471 bytes --]
On Thu, Nov 05, 2026 at 02:38:06PM +0000, Lee Jones wrote:
> axi_pwmgen_probe() calls axi_pwmgen_setup(), which reads and writes MMIO
> registers to verify the IP core version and determine the channel count,
> before acquiring and enabling axi_clk. If the bootloader leaves the AXI
> peripheral clock gated, accessing the registers causes an unclocked bus
> access fault.
Do you have the hardware? Or what convinced you that an access fault
happens?
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe()
2026-11-05 15:48 ` Uwe Kleine-König
@ 2026-11-05 18:26 ` Lee Jones
2026-11-05 18:26 ` Lee Jones
0 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-05 18:26 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Michael Hennerich, Nuno Sá, Trevor Gamblin, Sergiu Cuciurean,
Drew Fustini, linux-pwm, linux-kernel, stable
On Thu, 05 Nov 2026, Uwe Kleine-König wrote:
> On Thu, Nov 05, 2026 at 02:38:06PM +0000, Lee Jones wrote:
> > axi_pwmgen_probe() calls axi_pwmgen_setup(), which reads and writes MMIO
> > registers to verify the IP core version and determine the channel count,
> > before acquiring and enabling axi_clk. If the bootloader leaves the AXI
> > peripheral clock gated, accessing the registers causes an unclocked bus
> > access fault.
>
> Do you have the hardware? Or what convinced you that an access fault
> happens?
These are Sashiko bugs, as we discussed out-of-band.
None of these have been tested on real h/w.
--
Lee Jones
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe()
2026-11-05 18:26 ` Lee Jones
@ 2026-11-05 18:26 ` Lee Jones
0 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-05 18:26 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Michael Hennerich, Nuno Sá, Trevor Gamblin, Sergiu Cuciurean,
Drew Fustini, linux-pwm, linux-kernel, stable
On Thu, 05 Nov 2026, Lee Jones wrote:
> On Thu, 05 Nov 2026, Uwe Kleine-König wrote:
>
> > On Thu, Nov 05, 2026 at 02:38:06PM +0000, Lee Jones wrote:
> > > axi_pwmgen_probe() calls axi_pwmgen_setup(), which reads and writes MMIO
> > > registers to verify the IP core version and determine the channel count,
> > > before acquiring and enabling axi_clk. If the bootloader leaves the AXI
> > > peripheral clock gated, accessing the registers causes an unclocked bus
> > > access fault.
> >
> > Do you have the hardware? Or what convinced you that an access fault
> > happens?
>
> These are Sashiko bugs, as we discussed out-of-band.
>
> None of these have been tested on real h/w.
I'll make that clear in the cover-letters going forward.
--
Lee Jones
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 5/8] pwm: fsl-ftm: Enable ipg_clk around regcache_sync() during resume
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
` (3 preceding siblings ...)
2026-11-05 14:38 ` [PATCH 4/8] pwm: axi-pwmgen: Enable clocks before accessing hardware registers in probe() Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 14:38 ` [PATCH 6/8] pwm: omap-dmtimer: Handle negative error codes from get_pwm_status() Lee Jones
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Uwe Kleine-König, Xiubo Li, shenwei.wang@nxp.com,
Thierry Reding, linux-pwm, linux-kernel
Cc: stable
On SoCs with a dedicated IP interface clock (ipg_clk), register accesses
require ipg_clk to be enabled in addition to the ftm_sys clock managed
by regmap_mmio. In fsl_pwm_resume(), ipg_clk is only enabled inside the
channel loop for channels with PWMF_REQUESTED set, so if no channels are
currently requested, regcache_sync() writes to the hardware registers
while ipg_clk is disabled.
Enable ipg_clk across fsl_pwm_resume() around regcache_sync(), matching
fsl_pwm_init().
Fixes: 82a9c55a2bb0 ("pwm: fsl-ftm: Added a dedicated IP interface clock")
Closes: https://sashiko.dev/#/bug/linux-858851cf-55a9-4776-883c-69c05f3961f2
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-fsl-ftm.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 35406b2e1925..9e5470e2efe6 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -501,8 +501,13 @@ static int fsl_pwm_resume(struct device *dev)
{
struct pwm_chip *chip = dev_get_drvdata(dev);
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
+ int ret;
int i;
+ ret = clk_prepare_enable(fpc->ipg_clk);
+ if (ret)
+ return ret;
+
for (i = 0; i < chip->npwm; i++) {
struct pwm_device *pwm = &chip->pwms[i];
@@ -522,6 +527,8 @@ static int fsl_pwm_resume(struct device *dev)
regcache_cache_only(fpc->regmap, false);
regcache_sync(fpc->regmap);
+ clk_disable_unprepare(fpc->ipg_clk);
+
return 0;
}
#endif
Cc: shenwei.wang@nxp.com
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 6/8] pwm: omap-dmtimer: Handle negative error codes from get_pwm_status()
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
` (4 preceding siblings ...)
2026-11-05 14:38 ` [PATCH 5/8] pwm: fsl-ftm: Enable ipg_clk around regcache_sync() during resume Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 14:38 ` [PATCH 7/8] pwm: tiehrpwm: Enable runtime PM before registering PWM chip Lee Jones
2026-11-05 14:38 ` [PATCH 8/8] pwm: img: Unregister PWM chip before disabling runtime PM and clocks Lee Jones
7 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Uwe Kleine-König, Neil Armstrong, Joachim Eastwood,
NeilBrown, Grant Erickson, Thierry Reding, Lokesh Vutla,
linux-pwm, linux-kernel
Cc: stable
omap->pdata->get_pwm_status() returns a signed int that can be a
negative error code on runtime PM failure or invalid timer cookie.
pwm_omap_dmtimer_is_enabled() and pwm_omap_dmtimer_polarity() store the
return value in an unsigned u32 and test OMAP_TIMER_CTRL_ST (BIT(0)) and
OMAP_TIMER_CTRL_SCPWM (BIT(7)), misinterpreting negative error codes
(such as -EINVAL or -EACCES) as an enabled or inverted timer.
Store the return value in a signed int and check for negative error
codes before testing register bits.
Fixes: 6b28fb6f3ca3 ("pwm: omap-dmtimer: Implement .apply callback")
Closes: https://sashiko.dev/#/bug/linux-f4782faa-466d-43a8-85d8-6d6181ee2243
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-omap-dmtimer.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 51830a87275c..1e4d8b9e224f 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -111,9 +111,11 @@ static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap)
*/
static bool pwm_omap_dmtimer_is_enabled(struct pwm_omap_dmtimer_chip *omap)
{
- u32 status;
+ int status;
status = omap->pdata->get_pwm_status(omap->dm_timer);
+ if (status < 0)
+ return false;
return !!(status & OMAP_TIMER_CTRL_ST);
}
@@ -126,9 +128,11 @@ static bool pwm_omap_dmtimer_is_enabled(struct pwm_omap_dmtimer_chip *omap)
*/
static int pwm_omap_dmtimer_polarity(struct pwm_omap_dmtimer_chip *omap)
{
- u32 status;
+ int status;
status = omap->pdata->get_pwm_status(omap->dm_timer);
+ if (status < 0)
+ return PWM_POLARITY_NORMAL;
return !!(status & OMAP_TIMER_CTRL_SCPWM);
}
Cc: Lokesh Vutla <lokeshvutla@ti.com>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 7/8] pwm: tiehrpwm: Enable runtime PM before registering PWM chip
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
` (5 preceding siblings ...)
2026-11-05 14:38 ` [PATCH 6/8] pwm: omap-dmtimer: Handle negative error codes from get_pwm_status() Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
2026-11-05 14:38 ` [PATCH 8/8] pwm: img: Unregister PWM chip before disabling runtime PM and clocks Lee Jones
7 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Uwe Kleine-König, Philip, Avinash, Vaibhav Bedia,
Thierry Reding, linux-pwm, linux-kernel
Cc: stable
ehrpwm_pwm_probe() calls pwmchip_add() before setting driver data and
enabling runtime PM. Because pwmchip_add() immediately exposes the PWM
channels to consumers, a consumer can invoke ehrpwm_pwm_apply() before
pm_runtime_enable() runs, causing registers to be accessed while the
device remains runtime-suspended.
Set driver data and enable runtime PM before calling pwmchip_add(), and
disable runtime PM on the error path.
Fixes: 19891b20e7c2 ("pwm: pwm-tiehrpwm: PWM driver support for EHRPWM")
Closes: https://sashiko.dev/#/bug/linux-28b36a80-e4a9-4bb6-97bc-7ca02895570a
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-tiehrpwm.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index e3407d0a1f7f..f9dd3b91c73a 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -461,18 +461,19 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
return ret;
}
- ret = pwmchip_add(chip);
- if (ret < 0) {
- dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
- goto err_clk_unprepare;
- }
-
platform_set_drvdata(pdev, chip);
pm_runtime_enable(&pdev->dev);
+ ret = pwmchip_add(chip);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+ goto err_pm_disable;
+ }
+
return 0;
-err_clk_unprepare:
+err_pm_disable:
+ pm_runtime_disable(&pdev->dev);
clk_unprepare(pc->tbclk);
return ret;
Cc: "Philip, Avinash" <avinashphilip@ti.com>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 8/8] pwm: img: Unregister PWM chip before disabling runtime PM and clocks
2026-11-05 14:38 [PATCH 0/8] pwm: Fix various bugs reported by Sashiko Lee Jones
` (6 preceding siblings ...)
2026-11-05 14:38 ` [PATCH 7/8] pwm: tiehrpwm: Enable runtime PM before registering PWM chip Lee Jones
@ 2026-11-05 14:38 ` Lee Jones
7 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-05 14:38 UTC (permalink / raw)
To: lee, Uwe Kleine-König, Sai Masarapu, Vladimir Zapolskiy,
Naidu Tellapati, Ezequiel Garcia, Thierry Reding,
Andrew Bresticker, linux-pwm, linux-kernel
Cc: stable
img_pwm_remove() disables runtime PM and gates the peripheral clocks via
img_pwm_runtime_suspend() before calling pwmchip_remove(). While the
PWM chip is still registered, a consumer can call img_pwm_apply(), where
pm_runtime_resume_and_get() returns -EACCES or succeeds without
re-enabling clocks, leading to unclocked register access.
Call pwmchip_remove() before disabling runtime PM and suspending the
device.
Fixes: 277bb6a29e00 ("pwm: Imagination Technologies PWM DAC driver")
Closes: https://sashiko.dev/#/bug/linux-b06bab8d-dbf2-4ba2-9f5d-c5e141076abd
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
drivers/pwm/pwm-img.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c
index 91e0b19f0c08..b6e090674c07 100644
--- a/drivers/pwm/pwm-img.c
+++ b/drivers/pwm/pwm-img.c
@@ -338,11 +338,11 @@ static void img_pwm_remove(struct platform_device *pdev)
{
struct pwm_chip *chip = platform_get_drvdata(pdev);
- pm_runtime_disable(&pdev->dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
- img_pwm_runtime_suspend(&pdev->dev);
-
pwmchip_remove(chip);
+
+ pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_pwm_runtime_suspend(&pdev->dev);
}
#ifdef CONFIG_PM_SLEEP
Cc: Naidu Tellapati <naidu.tellapati@gmail.com>
--
2.56.0.398.g882cbad275-goog
^ permalink raw reply related [flat|nested] 14+ messages in thread