drivers/pwm/pwm-imx-tpm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
On a soft reset TPM PWM IP may preserve its internal state from
previous runtime, therefore on a subsequent OS boot and driver
probe "enable_count" value and TPM PWM IP internal channels
"enabled" states may get unaligned. In consequence on a suspend/resume
cycle the call "if (--tpm->enable_count == 0)" may lead to
"enable_count" overflow the system being blocked from entering
suspend due to:
if (tpm->enable_count > 0)
return -EBUSY;
Fix the problem by counting the enabled channels in probe function.
Signed-off-by: Viorel Suman (OSS) <viorel.suman@oss.nxp.com>
---
drivers/pwm/pwm-imx-tpm.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c
index 5b399de16d60..80fdb3303400 100644
--- a/drivers/pwm/pwm-imx-tpm.c
+++ b/drivers/pwm/pwm-imx-tpm.c
@@ -352,7 +352,7 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
struct clk *clk;
void __iomem *base;
int ret;
- unsigned int npwm;
+ unsigned int i, npwm;
u32 val;
base = devm_platform_ioremap_resource(pdev, 0);
@@ -382,6 +382,13 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
mutex_init(&tpm->lock);
+ /* count the enabled channels */
+ for (i = 0; i < npwm; ++i) {
+ val = readl(base + PWM_IMX_TPM_CnSC(i));
+ if (FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val))
+ ++tpm->enable_count;
+ }
+
ret = devm_pwmchip_add(&pdev->dev, chip);
if (ret)
return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
--
2.34.1
Hello, On Wed, Mar 11, 2026 at 02:33:09PM +0200, Viorel Suman (OSS) wrote: > On a soft reset TPM PWM IP may preserve its internal state from > previous runtime, therefore on a subsequent OS boot and driver > probe "enable_count" value and TPM PWM IP internal channels > "enabled" states may get unaligned. In consequence on a suspend/resume > cycle the call "if (--tpm->enable_count == 0)" may lead to > "enable_count" overflow the system being blocked from entering > suspend due to: > > if (tpm->enable_count > 0) > return -EBUSY; > > Fix the problem by counting the enabled channels in probe function. > > Signed-off-by: Viorel Suman (OSS) <viorel.suman@oss.nxp.com> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git pwm/for-next with Cc: stable. Given that the issue is already old (May 2019 in 5.2-rc1) I tend to not send it for inclusion into v7.0, but if something more urgent pops up I'll probably send it along. Best regards Uwe
On Wed, Mar 11, 2026 at 02:33:09PM +0200, Viorel Suman (OSS) wrote:
> On a soft reset TPM PWM IP may preserve its internal state from
> previous runtime, therefore on a subsequent OS boot and driver
> probe "enable_count" value and TPM PWM IP internal channels
> "enabled" states may get unaligned. In consequence on a suspend/resume
> cycle the call "if (--tpm->enable_count == 0)" may lead to
> "enable_count" overflow the system being blocked from entering
> suspend due to:
>
> if (tpm->enable_count > 0)
> return -EBUSY;
>
> Fix the problem by counting the enabled channels in probe function.
Fix tag here
Frank
>
> Signed-off-by: Viorel Suman (OSS) <viorel.suman@oss.nxp.com>
> ---
> drivers/pwm/pwm-imx-tpm.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pwm/pwm-imx-tpm.c b/drivers/pwm/pwm-imx-tpm.c
> index 5b399de16d60..80fdb3303400 100644
> --- a/drivers/pwm/pwm-imx-tpm.c
> +++ b/drivers/pwm/pwm-imx-tpm.c
> @@ -352,7 +352,7 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
> struct clk *clk;
> void __iomem *base;
> int ret;
> - unsigned int npwm;
> + unsigned int i, npwm;
> u32 val;
>
> base = devm_platform_ioremap_resource(pdev, 0);
> @@ -382,6 +382,13 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
>
> mutex_init(&tpm->lock);
>
> + /* count the enabled channels */
> + for (i = 0; i < npwm; ++i) {
> + val = readl(base + PWM_IMX_TPM_CnSC(i));
> + if (FIELD_GET(PWM_IMX_TPM_CnSC_ELS, val))
> + ++tpm->enable_count;
> + }
> +
> ret = devm_pwmchip_add(&pdev->dev, chip);
> if (ret)
> return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
> --
> 2.34.1
>
On Wed, Mar 11, 2026 at 11:35:10AM -0400, Frank Li wrote:
> On Wed, Mar 11, 2026 at 02:33:09PM +0200, Viorel Suman (OSS) wrote:
> > On a soft reset TPM PWM IP may preserve its internal state from
> > previous runtime, therefore on a subsequent OS boot and driver
> > probe "enable_count" value and TPM PWM IP internal channels
> > "enabled" states may get unaligned. In consequence on a suspend/resume
> > cycle the call "if (--tpm->enable_count == 0)" may lead to
> > "enable_count" overflow the system being blocked from entering
> > suspend due to:
> >
> > if (tpm->enable_count > 0)
> > return -EBUSY;
> >
> > Fix the problem by counting the enabled channels in probe function.
>
> Fix tag here
No need to resend just for that. I'll add
Fixes: 738a1cfec2ed ("pwm: Add i.MX TPM PWM driver support")
Cc: stable@vger.kernel.org
when committing.
Thanks
Uwe
© 2016 - 2026 Red Hat, Inc.