Re: [PATCH v4 1/2] irqchip/imx-irqsteer: Convert to devm_pm_runtime_enable()
From: Frank Li
Date: Wed Aug 19 2026 - 12:28:13 EST
On Mon, Aug 17, 2026 at 04:06:20PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <festevam@xxxxxxxxxxxx>
>
> imx_irqsteer_probe() enables runtime PM, but imx_irqsteer_remove() does
> not disable it. Consequently, runtime PM remains enabled after unbinding
> the device, and rebinding it triggers:
>
> Unbalanced pm_runtime_enable!
>
> Use devm_pm_runtime_enable() to automatically disable runtime PM when
> the device is removed.
>
> The driver core may runtime suspend the device before calling remove.
> In that case, the runtime suspend callback has already disabled the IPG
> clock, so only disable it in remove when the device is still active.
>
> Set up runtime PM before creating the IRQ domain and registering chained
> handlers so that a failure cannot leave either resource pointing at
> freed driver data.
>
> Fixes: 4730d2233311 ("irqchip/imx-irqsteer: Add runtime PM support")
> Signed-off-by: Fabio Estevam <festevam@xxxxxxxxxxxx>
> ---
> Changes since v3:
> - Do not disable the IPG clock in remove when runtime PM has already
> suspended the device, preventing a clock reference-count underflow. (Radu)
>
> drivers/irqchip/irq-imx-irqsteer.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
> index 87b07f517be3..f4df5ae73e9a 100644
> --- a/drivers/irqchip/irq-imx-irqsteer.c
> +++ b/drivers/irqchip/irq-imx-irqsteer.c
> @@ -236,6 +236,11 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
> if (irqsteer_has_chanctrl(data->devtype_data))
> writel_relaxed(BIT(data->channel), data->regs + CHANCTRL);
>
> + pm_runtime_set_active(&pdev->dev);
> + ret = devm_pm_runtime_enable(&pdev->dev);
devm_pm_runtime_active_enable() do both work by one call.
Frank
> + if (ret)
> + goto out;
> +
> data->domain = irq_domain_create_linear(dev_fwnode(&pdev->dev), data->reg_num * 32,
> &imx_irqsteer_domain_ops, data);
> if (!data->domain) {
> @@ -262,9 +267,6 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> - pm_runtime_set_active(&pdev->dev);
> - pm_runtime_enable(&pdev->dev);
> -
> return 0;
> out:
> clk_disable_unprepare(data->ipg_clk);
> @@ -286,7 +288,8 @@ static void imx_irqsteer_remove(struct platform_device *pdev)
>
> irq_domain_remove(irqsteer_data->domain);
>
> - clk_disable_unprepare(irqsteer_data->ipg_clk);
> + if (!pm_runtime_status_suspended(&pdev->dev))
> + clk_disable_unprepare(irqsteer_data->ipg_clk);
> }
>
> #ifdef CONFIG_PM
> --
> 2.43.0
>