Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: Zhipeng.wang_1@oss.nxp.com
Cc: imx@lists.linux.dev, Frank.Li@kernel.org
Subject: Re: [PATCH v3 4/4] irqchip/imx-irqsteer: Allow building as module
Date: Fri, 07 Aug 2026 08:29:56 +0000	[thread overview]
Message-ID: <20260807082957.49A791F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260807072346.1222389-5-Zhipeng.wang_1@oss.nxp.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Missing explicit runtime PM management in `remove()` causes a hardware access crash and a clock enable count underflow during devres cleanup.

Pre-existing issues:
- [High] The chained IRQ handler accesses hardware registers unconditionally without ensuring the device's clock is enabled, which can crash the system on spurious interrupts.
--

--- Patch [4]: [PATCH v3 4/4] irqchip/imx-irqsteer: Allow building as module ---
commit d2409da6cb54e5e7df533908b454c22db10f15a7
Author: Jindong Yue <jindong.yue@nxp.com>

irqchip/imx-irqsteer: Allow building as module

Make the driver buildable as a module by turning the Kconfig symbol into
a tristate and using module_platform_driver() instead of
builtin_platform_driver(). Let the driver core own the clock and runtime PM
lifetime so that remove() does not have to hand-balance them.

> diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
> index 0c9c99f1141a9..e62862617b8d1 100644
> --- a/drivers/irqchip/irq-imx-irqsteer.c
> +++ b/drivers/irqchip/irq-imx-irqsteer.c

[ ... ]

> @@ -266,15 +260,22 @@ 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);
> +	ret = devm_pm_runtime_set_active_enabled(&pdev->dev);
> +	if (ret)
> +		goto err_irq;

[Severity: High]
This is a pre-existing issue, but does the chained IRQ handler access hardware
registers unconditionally without ensuring the device's clock is enabled?

If no child interrupts are requested by client drivers, the irqsteer device
drops its PM usage count to 0 and enters runtime suspend, disabling ipg_clk.
However, the parent interrupt handler imx_irqsteer_irq_handler remains
registered and active with the core IRQ subsystem.

If a spurious interrupt arrives while the device is suspended, the handler
executes and directly reads the CHANSTATUS register:

drivers/irqchip/irq-imx-irqsteer.c:imx_irqsteer_irq_handler() {
	...
	irqmap = readl_relaxed(data->regs + CHANSTATUS(idx, data->reg_num));
	...
}

Accessing memory-mapped registers of an IP block with a gated interface clock
can trigger a hardware fault (external abort / bus fault).

Should the handler use pm_runtime_get_if_active() to verify the power state
before accessing hardware?

[ ... ]

> @@ -302,8 +303,6 @@ static void imx_irqsteer_remove(struct platform_device *pdev)
>  						     hwirq));
>  
>  	irq_domain_remove(irqsteer_data->domain);
> -
> -	clk_disable_unprepare(irqsteer_data->ipg_clk);
>  }

[Severity: High]
Does this change cause a hardware access crash during driver unbind?

On driver unbind, the driver core drops its PM reference by calling
pm_runtime_put_sync() before invoking the driver's remove callback. Since no
children are holding PM references, the device suspends synchronously, and
imx_irqsteer_suspend() disables ipg_clk.

When imx_irqsteer_remove() executes, it writes to CHANMASK hardware registers
with a disabled clock, which can trigger a fatal bus fault:

drivers/irqchip/irq-imx-irqsteer.c:imx_irqsteer_remove() {
	...
	for (i = 0; i < irqsteer_data->reg_num; i++)
		writel_relaxed(0, irqsteer_data->regs +
			       CHANMASK(i, irqsteer_data->reg_num));
	...
}

Additionally, devres teardown runs after remove() in LIFO order and unwinds
devm_clk_get_enabled() by calling clk_disable_unprepare(). This decrements
the already-zero clock enable count, throwing a WARN and corrupting the clock
tree.

Should the driver explicitly wake the device in remove() (e.g., via
pm_runtime_get_sync()) before accessing registers?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260807072346.1222389-1-Zhipeng.wang_1@oss.nxp.com?part=4

      reply	other threads:[~2026-08-07  8:29 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-07  7:23 [PATCH v3 0/4] irqchip/imx-irqsteer: Allow building as module Zhipeng.wang_1
2026-08-07  7:23 ` [PATCH v3 1/4] irqchip/imx-irqsteer: Fix error handling path in probe() Zhipeng.wang_1
2026-08-07  7:45   ` sashiko-bot
2026-08-07 19:01   ` Frank Li
2026-08-07  7:23 ` [PATCH v3 2/4] irqchip/imx-irqsteer: Dispose of IRQ mappings in remove() Zhipeng.wang_1
2026-08-07 19:11   ` Frank Li
2026-08-07  7:23 ` [PATCH v3 3/4] irqchip/imx-irqsteer: Mask all interrupts in probe() and remove() Zhipeng.wang_1
2026-08-07  8:12   ` sashiko-bot
2026-08-07 19:14   ` Frank Li
2026-08-07  7:23 ` [PATCH v3 4/4] irqchip/imx-irqsteer: Allow building as module Zhipeng.wang_1
2026-08-07  8:29   ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260807082957.49A791F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=Zhipeng.wang_1@oss.nxp.com \
    --cc=imx@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox