From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Jiawen Liu <1298662399@qq.com>, Mark Brown <broonie@kernel.org>,
Sasha Levin <sashal@kernel.org>,
han.xu@nxp.com, haibo.chen@nxp.com, linux-spi@vger.kernel.org,
imx@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18-6.12] spi: nxp-fspi: disable runtime PM on probe failures
Date: Mon, 19 Oct 2026 09:49:15 -0400 [thread overview]
Message-ID: <20261019135441.1420968-264-sashal@kernel.org> (raw)
In-Reply-To: <20261019135441.1420968-1-sashal@kernel.org>
From: Jiawen Liu <1298662399@qq.com>
[ Upstream commit 5d14285d60ba95561609a293064654a0c7d7d928 ]
nxp_fspi_probe() enables runtime PM and autosuspend before
several operations that can fail.
Some failure paths returned directly before the devm cleanup
action was installed, leaving runtime PM enabled.
Route those failures through a common runtime PM cleanup path.
Use pm_runtime_resume_and_get() for the initial clock enable.
Signed-off-by: Jiawen Liu <1298662399@qq.com>
Link: https://patch.msgid.link/tencent_8FC0B8DFAF4AE67AEBA20548045D53A77707@qq.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
I have enough to decide: the leak is in this 6.18 tree, the fix is small
and self-contained, and it does not depend on later rework.
## Phase 1: Commit message forensics
**Step 1.1: Subject line**
Record: **[spi: nxp-fspi]** **[disable]** disable runtime PM on probe
failures. Action is a cleanup of leftover runtime PM after
`nxp_fspi_probe()` fails.
**Step 1.2: Tags**
Record:
- `Signed-off-by: Jiawen Liu <1298662399@qq.com>` (author)
- `Link: https://patch.msgid.link/tencent_8FC0B8DFAF4AE67AEBA20548045D53
A77707@qq.com`
- `Signed-off-by: Mark Brown <broonie@kernel.org>` (SPI maintainer
applied it)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, or `Cc: stable` (absence is expected)
- Pipeline `Signed-off-by: Sasha Levin` / `[Upstream commit
5d14285d60ba...]` ignored as candidate-prep markers
**Step 1.3: Body**
Record:
- **Bug:** `nxp_fspi_probe()` calls `pm_runtime_enable()` + autosuspend,
then can fail before `devm_add_action_or_reset(..., nxp_fspi_cleanup,
...)`.
- **Symptom:** runtime PM left enabled after a failed probe; no
`nxp_fspi_cleanup()` to disable it.
- **Root cause:** early `return` on clock get/put, IRQ request, and
mutex init.
- **Fix:** common `err_disable_pm` path; switch initial get to
`pm_runtime_resume_and_get()`.
- **Version info in message:** none.
**Step 1.4: Hidden bug fix?**
Record: Not hidden. This is an explicit probe error-path resource-leak
fix.
## Phase 2: Diff analysis
**Step 2.1: Inventory**
Record:
- File: `drivers/spi/spi-nxp-fspi.c` (+22 / −9)
- Function: `nxp_fspi_probe()` only
- Scope: single-file surgical error-path fix
**Step 2.2: Code flow**
Record (verified against parent of `03a9171de3f13`):
Before:
1. `pm_runtime_enable` / `use_autosuspend`
2. `pm_runtime_get_sync()` — on error, **return** (RPM stays enabled;
usage count stays incremented because `get_sync` increments even on
failure)
3. `pm_runtime_put_sync()` — on error, **return** (RPM stays enabled)
4. `devm_request_irq()` — on error, **return**
5. `devm_mutex_init()` — on error, **return**
6. Only later `devm_add_action_or_reset(..., nxp_fspi_cleanup)` disables
RPM
After: those four failures `goto err_disable_pm`, which does
`pm_runtime_dont_use_autosuspend()` + `pm_runtime_disable()`. Initial
get uses `pm_runtime_resume_and_get()` so a failed resume does **not**
leave the usage count up.
`devm_add_action_or_reset` failure still returns directly: on add
failure that helper already runs `nxp_fspi_cleanup()`, which disables
RPM. That path is correct as-is.
**Step 2.3: Bug mechanism**
Record: **Error-path resource leak** (runtime PM left enabled; usage-
count leak on failed `get_sync`). Also a small **correctness** change:
`get_sync` → `resume_and_get`, matching the kernel header guidance that
`get_sync` leaves the counter incremented on error.
**Step 2.4: Fix quality**
Record: Obviously correct and minimal. Regression risk is low: only
probe-failure paths plus the get API swap. Remaining gaps (unchecked
`nxp_fspi_default_setup()`, unchecked get in `nxp_fspi_cleanup()`) are
pre-existing and not introduced here.
## Phase 3: Git history
**Step 3.1: Blame**
Record: The buggy `pm_runtime_enable` / `get_sync` / early returns come
from `97be4b919a609` ("spi: spi-nxp-fspi: enable runtime pm for fspi",
Haibo Chen, 2025-04-28). Present in v6.16 and in this tree. Cleanup
action is `9f7cd1bcb6363` ("use devm instead of remove"), also in this
tree.
**Step 3.2: Fixes: tag**
Record: No `Fixes:` tag. Introducer is `97be4b919a609` (verified via
blame). `git merge-base --is-ancestor 97be4b919a609 v6.18` succeeds.
**Step 3.3: File history**
Record: Recent work is SoC clock/DTR features, not RPM probe cleanup. No
later commit on this file after the candidate. Standalone vs this file.
**Step 3.4: Author**
Record: Jiawen Liu submitted a 4-patch SPI PM error-path series
(atcspi200, bcmbca-hsspi, fsl-dspi, nxp-fspi). Not the driver
maintainer; NXP people (Han Xu, Haibo Chen) maintain this driver. Mark
Brown applied the series.
**Step 3.5: Dependencies**
Record: Cover letter says the four patches are independent. This hunk
only needs `pm_runtime_enable`/`use_autosuspend` (present) and
`pm_runtime_resume_and_get()` (present in `include/linux/pm_runtime.h`).
Can apply standalone. Applies cleanly to this tree’s probe function.
## Phase 4: Mailing list
**Step 4.1: Original discussion**
Record:
- `b4 dig -c 5d14285d60ba95561609a293064654a0c7d7d928` → https://patch.m
sgid.link/tencent_8FC0B8DFAF4AE67AEBA20548045D53A77707@qq.com
- Series: `[PATCH 0/4] spi: fix PM error handling in several drivers`
(2026-06-20), **v1 only** for this commit
- Cover letter: patches are independent; local error paths only
- Frank Li: style comment only — use `PM_RUNTIME_ACQUIRE` instead of
`goto` (not a NAK of the leak fix)
- Mark Brown applied the series to `for-7.3` as-is, including `[4/4]` as
`5d14285d60ba`
- sashiko-bot: this patch still leaves clocks on if `put_sync` fails;
also flagged pre-existing `default_setup` / cleanup get issues. Those
did **not** block merge.
**Step 4.2: Recipients (`b4 dig -w`)**
Record: Mark Brown, linux-spi, Han Xu, Haibo Chen, Yogesh Gaur,
imx@lists.linux.dev, linux-arm-kernel. Right maintainers were on Cc.
**Step 4.3: Bug report**
Record: No user/syzbot report. Found by code review of probe error
paths.
**Step 4.4: Related series**
Record: Later `[PATCH v2 0/3] spi: nxp-fspi: fix runtime PM error
handling` (2026-07-28) *reworks* this fix with
`devm_pm_runtime_enable()` / `PM_RUNTIME_ACQUIRE_AUTOSUSPEND()`, plus
`default_setup` and cleanup checks. That follow-up is **not** in this
tree (`rg` found no `devm_pm_runtime_enable` in the driver). Haibo Chen
rejected `PM_RUNTIME_ACQUIRE` in cleanup. The later series is extra
hardening/style, not a revert of this leak fix.
**Step 4.5: Stable list**
Record: lore.kernel.org search returned 403; no stable-thread evidence
obtained. UNVERIFIED whether anyone nominated this on stable@
separately.
## Phase 5: Semantic analysis
**Step 5.1: Functions**
Record: `nxp_fspi_probe()` only.
**Step 5.2: Callers**
Record: Platform `.probe = nxp_fspi_probe` in this file. Runs at device
bind / deferred probe, not from a syscall hot path.
**Step 5.3: Callees**
Record: `pm_runtime_resume_and_get`, `pm_runtime_put_sync`,
`devm_request_irq`, `devm_mutex_init`,
`pm_runtime_dont_use_autosuspend`, `pm_runtime_disable`. Runtime resume
enables clocks via `nxp_fspi_clk_prep_enable()`.
**Step 5.4: Reachability**
Record: Yes, from device probe on `CONFIG_SPI_NXP_FLEXSPI`
(i.MX8/i.MX9/Layerscape FlexSPI). Trigger is a **failed** probe after
RPM enable (clock resume fail, put fail, IRQ request fail, mutex init
fail). Not unprivileged userspace on a working board.
**Step 5.5: Similar patterns**
Record: Same author fixed other SPI PM error paths. `spi-rockchip.c`
already has `err_disable_pm_runtime`. This is a known driver pattern.
## Phase 6: Local tree (this checkout)
**Step 6.1: Does the bug exist here?**
Record:
- Tree: `v6.18.53-5049-g0f0bdc2b0dffb`, `Makefile` 6.18.53, branch
`autosel`
- Buggy sequence exists in `03a9171de3f13^` (`pm_runtime_get_sync` +
early returns after `pm_runtime_enable`)
- Introduced by `97be4b919a609`, ancestor of v6.18
- Driver file and RPM enablement are present
**Step 6.2: Backport difficulty**
Record: **Clean apply**. Context matches this tree (`device_set_node`
and DTR caps are already here). `pm_runtime_resume_and_get()` exists.
**Step 6.3: Related fixes already here?**
Record: No other probe RPM-disable fix. Later v2 rework is not present.
`nxp_fspi_cleanup()` still disables RPM only after successful
`devm_add_action_or_reset`.
## Phase 7: Subsystem context
**Step 7.1:** `drivers/spi/` — NXP FlexSPI (`CONFIG_SPI_NXP_FLEXSPI`).
Criticality: **IMPORTANT** for i.MX/Layerscape boards (often the
boot/SPI-NOR controller), **PERIPHERAL** for everyone else.
**Step 7.2:** Actively maintained (clock/DTR/DLL work through
2025–2026). RPM itself is from 6.16-era, so the leak has been in 6.18
for the life of this driver feature.
## Phase 8: Impact and risk
**Step 8.1: Who is affected**
Record: Users of NXP FlexSPI (`nxp,imx8mm-fspi`, `imx8mp`, `imx8ulp`,
`imx93`, `imx95`, `lx2160a-fspi`, etc.) when probe fails after RPM is
enabled.
**Step 8.2: Trigger**
Record: Failed probe after `pm_runtime_enable()`. Not every boot. Clock
resume failure is the important case: old `get_sync` leaves `usage_count
> 0` and RPM enabled, so a later bind hits `pm_runtime_enable()` on an
already-enabled device (WARN). IRQ/mutex failures after a successful put
leave RPM enabled on an unbound device.
Cannot be triggered by an unprivileged user on a healthy probe path.
**Step 8.3: Failure mode**
Record:
- Runtime PM enabled after failed bind
- Failed `get_sync`: usage-count leak, device stuck “active”
- Re-probe: `pm_runtime_enable()` WARN
- Autosuspend still armed if put succeeded before a later failure
Severity: **MEDIUM** (probe error path, not a success-path
crash/corruption). Still a real leak/WARN class that stable regularly
takes.
**Step 8.4: Risk-benefit**
Record:
- **Benefit:** Medium for i.MX/Layerscape; stops leftover RPM state and
usage-count leak on failed probe.
- **Risk:** Low (~20 lines, error path only, recommended PM helper).
- Ratio supports backport.
## Phase 9: Synthesis
**Step 9.1: Evidence**
FOR:
- Real probe error-path leak: RPM enabled before `nxp_fspi_cleanup` is
installed
- `pm_runtime_get_sync()` on failure leaks the usage count;
`resume_and_get` + disable is the right fix
- Small, obviously correct, no new API
- Bug present since RPM was added (`97be4b919a609`), which is in this
6.18 tree
- SPI maintainer applied it; cover letter says the series is independent
- Driver is used on common NXP boards
AGAINST:
- No crash/syzbot/user report; probe-failure only
- Incomplete vs later review (ignored `nxp_fspi_default_setup()`,
cleanup get)
- Frank Li preferred helpers over `goto` (style; not a functional NAK)
UNRESOLVED:
- Could not fetch lore.kernel.org (403); discussion recovered via `b4
dig -m` and lkml.iu.edu
- No stable@ thread found
**Step 9.2: Stable rules**
1. Obviously correct and tested? **PASS** — maintainer applied; logic
matches PM docs
2. Real user-visible bug? **PASS** — leftover RPM / usage-count leak /
re-probe WARN
3. Important? **PASS** — resource leak that can WARN and leave PM state
wrong; not a success-path panic, but standard driver-core leak
4. Small and contained? **PASS** — one function, +22/−9
5. No new features/APIs? **PASS**
6. Applies to this tree? **PASS** — buggy code and helpers are here
**Step 9.3: Exception category**
Record: Not a device-ID/quirk/DT/build/docs exception. Ordinary error-
path leak fix.
**Step 9.4: Decision**
This 6.18 tree has the leak. The patch is a small, correct disable of
runtime PM on probe failures, with the right `resume_and_get` pairing.
Later optional rework is not a reason to skip this.
### What it solves for stable users
On NXP FlexSPI, probe currently enables runtime PM, then can return on
clock/IRQ/mutex failure before the devm cleanup action. That leaves RPM
enabled (and, with `get_sync`, an elevated usage count). A later bind
can WARN. The patch disables RPM on those paths.
### Risk vs benefit
Low risk, clear benefit on a widely used embedded SPI-NOR controller. No
prerequisites beyond code already in 6.18.
---
Verification:
- [Phase 1] Parsed tags: author Jiawen Liu, Link msgid, SOB Mark Brown;
no Fixes/Reported-by/Cc stable
- [Phase 2] Diff: `nxp_fspi_probe()` +22/−9; four early returns →
`err_disable_pm`; `get_sync` → `resume_and_get`
- [Phase 2] Confirmed `pm_runtime_get_sync` increments usage even on
error (`include/linux/pm_runtime.h`); `resume_and_get` does not
- [Phase 3] `git describe HEAD` / `make kernelversion`: **6.18.53**,
branch `autosel`
- [Phase 3] `git blame` on parent: leak from `97be4b919a609`
(2025-04-28)
- [Phase 3] `git merge-base --is-ancestor 97be4b919a609 v6.18`: yes
(also in v6.16)
- [Phase 3] Parent probe still has `get_sync` + bare returns after
`pm_runtime_enable`
- [Phase 4] `b4 dig -c 5d14285d60ba`: PATCH 4/4, lore msgid above
- [Phase 4] `b4 dig -a`: v1 only for this commit
- [Phase 4] `b4 dig -w`: Mark Brown, Han Xu, Haibo Chen, linux-spi, imx
list
- [Phase 4] mbox: Frank Li style comment; Mark Brown applied 4/4 to
for-7.3; cover letter says independent
- [Phase 4] Later v2 rework (Jul 2026) not in this tree
- [Phase 5] Probe is platform `.probe`; Kconfig `SPI_NXP_FLEXSPI` for
i.MX/Layerscape
- [Phase 6] `pm_runtime_resume_and_get` exists; patch context matches
local probe
- [Phase 8] Failure mode: RPM leak / usage-count leak / re-probe WARN,
not a hot-path oops
- UNVERIFIED: lore.kernel.org HTTP 403; no dedicated stable@ discussion
found
**YES**
drivers/spi/spi-nxp-fspi.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index b504a5c86692a..0300f4ae1455d 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -1426,9 +1426,11 @@ static int nxp_fspi_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(dev);
/* enable clock */
- ret = pm_runtime_get_sync(f->dev);
- if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to enable clock");
+ ret = pm_runtime_resume_and_get(f->dev);
+ if (ret < 0) {
+ ret = dev_err_probe(dev, ret, "Failed to enable clock");
+ goto err_disable_pm;
+ }
/* Clear potential interrupts */
reg = fspi_readl(f, f->iobase + FSPI_INTR);
@@ -1438,18 +1440,24 @@ static int nxp_fspi_probe(struct platform_device *pdev)
nxp_fspi_default_setup(f);
ret = pm_runtime_put_sync(dev);
- if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to disable clock");
+ if (ret < 0) {
+ ret = dev_err_probe(dev, ret, "Failed to disable clock");
+ goto err_disable_pm;
+ }
init_completion(&f->c);
ret = devm_request_irq(dev, irq,
nxp_fspi_irq_handler, 0, pdev->name, f);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to request irq\n");
+ if (ret) {
+ ret = dev_err_probe(dev, ret, "Failed to request irq\n");
+ goto err_disable_pm;
+ }
ret = devm_mutex_init(dev, &f->lock);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to initialize lock\n");
+ if (ret) {
+ ret = dev_err_probe(dev, ret, "Failed to initialize lock\n");
+ goto err_disable_pm;
+ }
ctlr->bus_num = -1;
ctlr->num_chipselect = NXP_FSPI_MAX_CHIPSELECT;
@@ -1467,6 +1475,11 @@ static int nxp_fspi_probe(struct platform_device *pdev)
return ret;
return devm_spi_register_controller(&pdev->dev, ctlr);
+
+err_disable_pm:
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_disable(dev);
+ return ret;
}
static int nxp_fspi_runtime_suspend(struct device *dev)
--
2.53.0
next parent reply other threads:[~2026-10-19 14:01 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20261019135441.1420968-1-sashal@kernel.org>
2026-10-19 13:49 ` Sasha Levin [this message]
2026-10-19 13:49 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18-5.10] firmware: imx: scu: manage mailbox channels and global handle Sasha Levin
2026-10-19 15:12 ` sashiko-bot
2026-10-19 13:51 ` [PATCH AUTOSEL 6.18] spi: fsl-dspi: clean up after failed suspend and resume Sasha Levin
2026-10-19 15:19 ` sashiko-bot
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-5.10] clk: imx: imx8qxp-lpcg: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.12] i2c: imx-lpi2c: properly unwind resources on probe failure Sasha Levin
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=20261019135441.1420968-264-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=1298662399@qq.com \
--cc=broonie@kernel.org \
--cc=haibo.chen@nxp.com \
--cc=han.xu@nxp.com \
--cc=imx@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
/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