Re: Re: [PATCH v10 3/3] pwm: dwc: add of/platform support
"Xuyang Dong" <[email protected]> Thu, 9 Jul 2026 09:21:08 +0800 (GMT+08:00)
| Newsgroups | org.kernel.vger.linux-pwm,dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
> > Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: > > New issues: > - [High] Hardware reset is asserted after gating clocks, which can cause bus hangs. > - [High] Race condition between runtime PM check and disable causes a permanent clock leak. > > Pre-existing issues: > - [High] Unmasking the timer interrupt without an IRQ handler can cause a severe interrupt storm. > -- > > commit a50609ba96938c02fbc94f54318c95561f661758 > Author: Xuyang Dong <[email protected]> > Subject: pwm: dwc: add of/platform support > > The dwc pwm controller can be used in non-PCI systems, so allow either > platform or OF based probing. Implements polarity control by exploiting > the timer's dual load registers. > > > diff --git a/drivers/pwm/pwm-dwc-core.c b/drivers/pwm/pwm-dwc-core.c > > index 6dabec93a3c64..49f0657d4ad44 100644 > > --- a/drivers/pwm/pwm-dwc-core.c > > +++ b/drivers/pwm/pwm-dwc-core.c > > [ ... ] > > > @@ -85,6 +138,9 @@ static int __dwc_pwm_configure_timer(struct dwc_pwm *dwc, > > * periods are set by Load Count registers. > > */ > > ctrl = DWC_TIM_CTRL_MODE_USER | DWC_TIM_CTRL_PWM; > > + if (dwc->features & DWC_TIM_CTRL_0N100PWM_EN) > > + ctrl |= DWC_TIM_CTRL_0N100PWM_EN; > > + > > dwc_pwm_writel(dwc, ctrl, DWC_TIM_CTRL(pwm->hwpwm)); > > [Severity: High] > This isn't a bug introduced by this patch, but does writing this control > register unmask the timer interrupt? > > The ctrl value is constructed without DWC_TIM_CTRL_INT_MASK set. If this > hardware is on an OF platform where interrupts are commonly shared, could > this unmasked timer flood the system with interrupts since there is no > IRQ handler? > Hi Sashiko, Will add DWC_TIM_CTRL_INT_MASK in the next version. > > diff --git a/drivers/pwm/pwm-dwc-of.c b/drivers/pwm/pwm-dwc-of.c > > new file mode 100644 > > index 0000000000000..7bbbf98d7697a > > --- /dev/null > > +++ b/drivers/pwm/pwm-dwc-of.c > > [ ... ] > > > +static void dwc_pwm_plat_remove(struct platform_device *pdev) > > +{ > > + struct dwc_pwm_drvdata *data = platform_get_drvdata(pdev); > > + struct pwm_chip *chip = data->chips[0]; > > + struct dwc_pwm *dwc = to_dwc_pwm(chip); > > + unsigned int idx; > > + int ret; > > + > > + pwmchip_remove(chip); > > + > > + ret = pm_runtime_resume_and_get(&pdev->dev); > > + if (ret < 0) { > > + dev_warn(&pdev->dev, "failed to resume device: %d\n", ret); > > + } else { > > + for (idx = 0; idx < chip->npwm; idx++) { > > + if (dwc_pwm_readl(dwc, DWC_TIM_CTRL(idx)) & > > + DWC_TIM_CTRL_EN) > > + pm_runtime_put_noidle(&pdev->dev); > > + } > > + pm_runtime_put_sync(&pdev->dev); > > + } > > + > > + if (!pm_runtime_status_suspended(&pdev->dev)) { > > + clk_disable_unprepare(dwc->clk); > > + clk_disable_unprepare(dwc->bus_clk); > > + } > > + pm_runtime_disable(&pdev->dev); > > [Severity: High] > Could this ordering cause a permanent clock leak if a concurrent runtime > PM resume occurs? > > If userspace triggers a resume (e.g. via sysfs) between the > pm_runtime_status_suspended() check and pm_runtime_disable(), the > dwc_pwm_runtime_resume() callback will re-enable the clocks. > > Once pm_runtime_disable() runs, the PM state is frozen, but the driver will > have lost track of the re-enabled clocks. Should pm_runtime_disable() be > called before manually rolling back the clock state? > Call pm_runtime_disable() before manually rolling back the clock state. > > + > > + if (dwc->rst) { > > + ret = reset_control_assert(dwc->rst); > > [Severity: High] > Does asserting the reset while the IP block's clocks are disabled cause > a bus lockup? > > In dwc_pwm_plat_remove(), the clocks are guaranteed to be off here > (either implicitly by allowing the device to suspend, or explicitly via the > clk_disable_unprepare() calls just above). > > On AMBA/APB buses, asserting a reset on an unclocked IP block often prevents > the reset signal from propagating, leading to a system hang when the reset > controller attempts to complete the transaction. > Remove reset assert in remove function, as disabling PM and clocks prevents further operation Best regards, Xuyang Dong > > + if (ret) > > + dev_warn(&pdev->dev, "failed to assert reset: %d\n", > > + ret); > > + } > > +} > > -- > Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=3