* [PATCH AUTOSEL 6.18-5.10] iio: accel: mma8452: switch to non-devm request_threaded_irq()
[not found] <20260831133314.4125787-1-sashal@kernel.org>
@ 2026-08-31 13:21 ` Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.1] iio: light: stk3310: Deal with the ps interrupt issue in PM Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-31 13:21 UTC (permalink / raw)
To: patches, stable
Cc: Sanjay Chitroda, Jonathan Cameron, Sasha Levin, linux-iio,
linux-kernel
From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
[ Upstream commit 0a6726ec20cd4c0101f2de0ca485a11676224dea ]
Avoid using devm_request_threaded_irq() as the driver requires explicit
error-handling path(s). Using devm_* API together with goto-based
unwinding breaks the expected LIFO resource release model.
Add explicit IRQ cleanup in the driver teardown paths to follow kernel
resource management conventions.
Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit Message Forensics
**Step 1.1 — Subject line**
Record: `[iio: accel: mma8452]` `[switch]` — Replace
`devm_request_threaded_irq()` with manual `request_threaded_irq()` and
explicit `free_irq()` in probe error and remove paths.
**Step 1.2 — Tags**
Record:
- **Fixes:** — none
- **Reported-by:** — none
- **Tested-by:** — none
- **Reviewed-by:** — none
- **Acked-by:** — none
- **Link:** — none
- **Cc: stable:** — none (expected for manual review)
- **Signed-off-by:** Sanjay Chitroda (author), Jonathan Cameron (IIO
maintainer)
Notable: no fuzzer report, no user bug report, no explicit stable
nomination. Maintainer sign-off is present.
**Step 1.3 — Body analysis**
Record:
- **Bug:** `devm_request_threaded_irq()` combined with manual
`goto`-based probe unwind breaks devm’s LIFO release model; IRQ stays
registered while driver manually tears down buffer/trigger/other
resources.
- **Symptom:** Interrupt handler can run during manual teardown (probe
failure or `remove()`), accessing structures being destroyed.
- **Root cause:** devm releases IRQ only after probe returns or after
`remove()` completes, but the driver manually cleans up
buffer/trigger/regulators before that point.
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Despite “switch”/“conventions” wording, this is a real
teardown-order bug fix, not style-only cleanup.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- **File:** `drivers/iio/accel/mma8452.c` (+12 / −7)
- **Functions:** `mma8452_probe()`, `mma8452_remove()`
- **Scope:** Single-file surgical fix
**Step 2.2 — Code flow changes**
Record:
- **Hunk 1 (probe IRQ registration):** `devm_request_threaded_irq()` →
`request_threaded_irq()` — IRQ no longer tied to devm.
- **Hunk 2 (probe error paths):** After IRQ registration,
`pm_runtime_set_active()` / `iio_device_register()` failures now `goto
free_irq` instead of `goto buffer_cleanup`.
- **Hunk 3 (new `free_irq:` label):** Calls `free_irq(client->irq,
indio_dev)` before `buffer_cleanup`.
- **Hunk 4 (`remove()`):** Adds explicit `free_irq()` before
`iio_triggered_buffer_cleanup()`.
**Before → after on probe failure after IRQ setup:**
- Before: IRQ remains active through `buffer_cleanup` /
`trigger_cleanup`
- After: IRQ freed first, then buffer/trigger cleanup
**Before → after on `remove()`:**
- Before: IRQ active for entire `remove()`; devm frees only after
`remove()` returns
- After: IRQ freed before buffer/trigger teardown
**Step 2.3 — Bug mechanism**
Record: **Category:** teardown race / potential UAF in interrupt
context.
`mma8452_interrupt()` (lines 1053–1083) can call
`iio_trigger_poll_nested(indio_dev->trig)` and `iio_push_event()`. With
devm, IRQ stays live while `iio_triggered_buffer_cleanup()` and
`mma8452_trigger_cleanup()` run in probe error and remove paths.
**Step 2.4 — Fix quality**
Record: Fix is minimal, obviously correct, and matches standard non-devm
IRQ pattern. Low regression risk; no API changes.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: `devm_request_threaded_irq()` introduced in `28e3427824ccc8`
(2015-06-01, “iio: mma8452: Basic support for transient events”). Bug
present since v4.1 era; definitely present in this 6.18.y tree.
**Step 3.2 — Fixes: tag**
Record: N/A — no Fixes: tag.
**Step 3.3 — Related file history**
Record: Part of v3 series “iio: accel: mma8452: improve coding style, pm
and resource cleanup” (10 patches). Sibling patch `5bdff291d20c3`
(“handle I2C read error(s)”) **is already in this tree** as stable
commit `1cddef80a180a`. IRQ fix (`0a6726ec20cd4`) is **not** in this
tree.
**Step 3.4 — Author context**
Record: Sanjay Chitroda; Jonathan Cameron committed. Same author has
another teardown fix already backported here: `04a4d98222109`
(“ssp_sensors: cancel delayed work_refresh on remove”).
**Step 3.5 — Dependencies**
Record: **Standalone.** Does not depend on other series patches
(codestyle/header-sort patches are independent). `git apply --check` on
current tree: **clean apply**.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record: `b4 dig -c 0a6726ec20cd4` → [PATCH v3 02/10](https://patch.msgid
.link/20260505174640.3998281-3-sanjayembedded@gmail.com). Series v2 and
v3 found. Lore fetch blocked by bot protection; could not read thread
replies.
**Step 4.2 — Reviewers**
Record: `b4 dig -w` — CC’d: `jic23@kernel.org`, `linux-
iio@vger.kernel.org`, and other IIO maintainers/reviewers.
**Step 4.3 — Bug reports**
Record: None found.
**Step 4.4 — Series context**
Record: 10-patch series; this is patch 02/10. I2C read-error fix from
same series already backported to 6.18.y; IRQ fix was not.
**Step 4.5 — Stable list**
Record: UNVERIFIED — lore stable search inaccessible.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `mma8452_probe()`, `mma8452_remove()`, `mma8452_interrupt()`
**Step 5.2 — Callers**
Record: `mma8452_probe()` — I2C driver probe during device enumeration.
`mma8452_remove()` — device unbind/module unload. `mma8452_interrupt()`
— hardware IRQ thread.
**Step 5.3 — Callees in interrupt path**
Record: `i2c_smbus_read_byte_data()`, `iio_trigger_poll_nested()`,
`iio_push_event()` — all touch live IIO/trigger state.
**Step 5.4 — Reachability**
Record: Triggered when `client->irq` is non-zero (interrupt-capable
board config). Probe error path reachable on `iio_device_register()`
failure etc. Remove path runs on every unbind/unload.
**Step 5.5 — Similar patterns**
Record: Same devm+goto anti-pattern exists in other IIO drivers; this
fix is driver-specific.
---
## Phase 6: Cross-Reference Against Local Tree
**Step 6.1 — Buggy code present?**
Record: **Yes.** Local tree is **Linux 6.18.44** (`git describe HEAD` →
`v6.18.44`). `drivers/iio/accel/mma8452.c` still uses
`devm_request_threaded_irq()` at line 1685 with `goto buffer_cleanup` on
later failures; `remove()` has no `free_irq()`.
**Step 6.2 — Backport complications**
Record: **Clean apply** verified with `git apply --check`. No conflicts
expected.
**Step 6.3 — Related fixes already present?**
Record: `1cddef80a180a` (I2C read error propagation) is present. IRQ
teardown fix is **not** present.
---
## Phase 7: Subsystem Context
**Step 7.1 — Subsystem**
Record: `drivers/iio/accel/` — IIO accelerometer driver. **Criticality:
PERIPHERAL** (hardware-specific, not core kernel).
**Step 7.2 — Activity**
Record: Moderately active; several accel driver fixes backported to
6.18.y recently.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Systems with Freescale/NXP MMA8452-family accelerometer on I2C
**and** IRQ line configured (embedded/phone-class boards). Config-
dependent (`CONFIG_MMA8452` or module).
**Step 8.2 — Trigger conditions**
Record:
- **Probe failure** after IRQ registration (e.g. `iio_device_register()`
OOM) — uncommon
- **Driver remove/unbind** with IRQ configured and hardware generating
interrupts — more realistic
- Unprivileged users cannot directly trigger; requires device
presence/removal
**Step 8.3 — Failure mode severity**
Record: IRQ handler may access buffer/trigger/device state during
teardown → possible kernel oops/UAF in interrupt context. **Severity:
HIGH** (crash potential), but **low likelihood** (narrow race window, no
reports in ~11 years).
**Step 8.4 — Risk-benefit**
Record:
- **Benefit:** Prevents teardown race on probe error and remove; correct
resource ordering
- **Risk:** Very low (12-line, localized change)
- **Ratio:** Moderate benefit, very low risk
---
## Phase 9: Final Synthesis
**Step 9.1 — Evidence**
**FOR:**
- Real bug: IRQ active during manual teardown in probe error and remove
paths
- Interrupt handler touches IIO buffer/trigger state that is being
destroyed
- Small, surgical, maintainer-committed fix
- Applies cleanly to 6.18.y
- Bug present since 2015 in this driver
- Same author’s teardown fixes have been backported to this tree before
**AGAINST:**
- No crash reports, syzbot, or Fixes: tag
- Peripheral driver; only IRQ-enabled MMA8452 hardware
- Bug latent ~11 years without reported incidents
- Stable already took sibling I2C-read fix from same series but not this
one
- Framed as resource-management correctness rather than demonstrated
crash
**UNRESOLVED:**
- Lore thread review comments inaccessible
- No confirmation of real-world crash reproduction
**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — logic is sound; no Tested-by
but maintainer committed
2. Fixes a real bug? **PASS** — verified teardown ordering bug in code
3. Important issue? **PASS (borderline)** — crash/UAF potential on
remove, but unreported and hardware-specific
4. Small and contained? **PASS** — 19 lines, one file
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS** — verified clean apply
**Step 9.3 — Exception categories**
Record: None (not quirk/DT/build/docs).
**Step 9.4 — Decision rationale**
This is a legitimate teardown-order bug: with
`devm_request_threaded_irq()`, the IRQ remains registered while
`mma8452_remove()` and probe error paths manually destroy the triggered
buffer and trigger that `mma8452_interrupt()` uses. The fix is minimal,
correct, and applies cleanly to 6.18.44. Severity is borderline for
stable — no reported crashes, niche hardware — but the failure mode
(oops/UAF in IRQ context during driver removal) meets the conservative
stable bar for teardown races, especially given very low backport risk.
---
## Verification
- [Phase 1] `git show 0a6726ec20cd4 --format=fuller`: parsed message,
tags, no Fixes/Reported-by
- [Phase 2] `git show 0a6726ec20cd4`: confirmed +12/−7 diff in
probe/remove
- [Phase 2] Read `mma8452_interrupt()` at lines 1053–1083: handler uses
trigger/events during teardown
- [Phase 3] `git blame -L 1680,1720`: devm IRQ from `28e3427824ccc8`
(2015)
- [Phase 3] `git log all-next -- drivers/iio/accel/mma8452.c`: found
commit `0a6726ec20cd4`, series context
- [Phase 3] `git show 1cddef80a180a`: sibling I2C fix already in stable
6.18.y
- [Phase 3] `git apply --check` on patch: clean apply to HEAD
- [Phase 4] `b4 dig -c 0a6726ec20cd4`: lore URL found
- [Phase 4] `b4 dig -c 0a6726ec20cd4 -a`: v2/v3 series revisions found
- [Phase 4] `b4 dig -c 0a6726ec20cd4 -w`: maintainers CC’d
- [Phase 4] WebFetch lore URL: **FAILED** (bot protection)
- [Phase 5] Grep/read `mma8452.c`: confirmed interrupt →
`iio_trigger_poll_nested()` / `iio_push_event()`
- [Phase 6] `git describe HEAD`: v6.18.44
- [Phase 6] Grep `devm_request_threaded_irq` in tree: still present (bug
not fixed)
- [Phase 6] `git branch --contains 0a6726ec20cd4`: not in stable branch
- [Phase 7] `git log -20 -- drivers/iio/accel/`: subsystem activity
assessed
- [Phase 8] Read probe/remove error paths: confirmed `goto
buffer_cleanup` with active IRQ before fix
**YES**
drivers/iio/accel/mma8452.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index cefc7cf4bd835..279a9b3648860 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -1682,18 +1682,16 @@ static int mma8452_probe(struct i2c_client *client)
goto trigger_cleanup;
if (client->irq) {
- ret = devm_request_threaded_irq(&client->dev,
- client->irq,
- NULL, mma8452_interrupt,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- client->name, indio_dev);
+ ret = request_threaded_irq(client->irq, NULL, mma8452_interrupt,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ client->name, indio_dev);
if (ret)
goto buffer_cleanup;
}
ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
- goto buffer_cleanup;
+ goto free_irq;
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
@@ -1702,7 +1700,7 @@ static int mma8452_probe(struct i2c_client *client)
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto buffer_cleanup;
+ goto free_irq;
ret = mma8452_set_freefall_mode(data, false);
if (ret < 0)
@@ -1713,6 +1711,10 @@ static int mma8452_probe(struct i2c_client *client)
unregister_device:
iio_device_unregister(indio_dev);
+free_irq:
+ if (client->irq)
+ free_irq(client->irq, indio_dev);
+
buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
@@ -1738,6 +1740,9 @@ static void mma8452_remove(struct i2c_client *client)
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
+ if (client->irq)
+ free_irq(client->irq, indio_dev);
+
iio_triggered_buffer_cleanup(indio_dev);
mma8452_trigger_cleanup(indio_dev);
mma8452_standby(iio_priv(indio_dev));
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 6.18-6.1] iio: light: stk3310: Deal with the ps interrupt issue in PM
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-5.10] iio: accel: mma8452: switch to non-devm request_threaded_irq() Sasha Levin
@ 2026-08-31 13:23 ` Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] iio: adc: rtq6056: add i2c_device_id support Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.10] iio: adc: qcom-spmi-iadc: balance enable_irq_wake() on driver unbind Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-31 13:23 UTC (permalink / raw)
To: patches, stable
Cc: Miao Li, Jonathan Cameron, Sasha Levin, linux-iio, linux-kernel
From: Miao Li <limiao@kylinos.cn>
[ Upstream commit 9c1d639e90cf42f5c1401f91f38ffd89af6dd970 ]
On the Inspur HS326 laptop(which integrated with HiSilicon M900
processor), if the STK3311-X chip's PS interrupt is configured
in "Recommended interrupt mode", the interrupt cannot be triggered
normally after waking from suspend or hibernation.
In this case, neither disabling and re-enabling the interrupt nor
resetting the PS threshold register can restore the interrupt to
normal operation.
If the interrupt is disabled in suspend() then reset the PS threshold
register and enable the interrupt in resume(). This resolves the issue.
Signed-off-by: Miao Li <limiao@kylinos.cn>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit Message Forensics
**Step 1.1 — Subject line**
Record: `[iio: light: stk3310]` `[Deal with]` — PM workaround for
proximity-sensor (PS) interrupt handling across suspend/resume.
**Step 1.2 — Tags**
Record:
- **Signed-off-by:** Miao Li `<limiao@kylinos.cn>` (author)
- **Signed-off-by:** Jonathan Cameron `<jic23@kernel.org>` (IIO
maintainer)
- No `Fixes:`, `Reported-by:`, `Tested-by:`, `Reviewed-by:`, `Acked-
by:`, `Link:`, or `Cc: stable@vger.kernel.org` tags (expected for
manual review)
**Step 1.3 — Body analysis**
Record:
- **Bug:** On Inspur HS326 (HiSilicon M900) with STK3311-X, PS
interrupts in "Recommended interrupt mode" stop firing after
suspend/hibernation.
- **Symptom:** Proximity threshold interrupts never resume; userspace
cannot get proximity events after wake.
- **Root cause (author):** Standby-only PM is insufficient; the chip
needs PS interrupt disabled before suspend, PS threshold registers
rewritten, and interrupt re-enabled on resume.
- **Versions:** Not specified in the message; hardware-specific report.
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Although not labeled "fix", this is a real
suspend/resume functional bug. It also tightens error handling in
`stk3310_write_event()`, `stk3310_write_event_config()`, and
`stk3310_init()` (explicit error returns and state tracking).
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- **File:** `drivers/iio/light/stk3310.c` — ~69 insertions, ~7 deletions
- **Functions modified:** `stk3310_write_event()`,
`stk3310_write_event_config()`, `stk3310_init()`, `stk3310_suspend()`,
`stk3310_resume()`
- **Struct modified:** `stk3310_data` (+`ps_int_enabled`, `ps_thdl`,
`ps_thdh`)
- **Scope:** Single-file, surgical driver PM fix
**Step 2.2 — Code flow changes**
Record:
- **`stk3310_write_event()`:** Before: wrote threshold register,
returned error code without tracking. After: tracks
`ps_thdl`/`ps_thdh` in software on successful writes.
- **`stk3310_write_event_config()`:** Before: wrote interrupt enable,
returned `ret`. After: tracks `ps_int_enabled`, explicit unlock+return
on error.
- **`stk3310_init()`:** Before: enabled PS interrupt, returned `ret`
(could be non-zero on success path confusion). After: sets
`ps_int_enabled=true`, `ps_thdh=STK3310_PS_MAX_VAL`, returns 0 on
success.
- **`stk3310_suspend()`:** Before: only `stk3310_set_state(STANDBY)`.
After: disables PS interrupt first if enabled, then standby.
- **`stk3310_resume()`:** Before: only restored ALS/PS enable state.
After: restores state, rewrites threshold registers from cached
values, re-enables PS interrupt.
**Step 2.3 — Bug mechanism**
Record: **Hardware PM quirk / incomplete PM restore (category h).** The
driver's suspend/resume since 2015 only toggled sensor standby/enable
bits. It did not manage PS interrupt configuration or threshold
registers across PM cycles. On STK3311-X (Inspur HS326), this leaves the
interrupt path broken after wake.
**Step 2.4 — Fix quality**
Record: **Obviously correct** for the described hardware issue. Minimal
state cache mirrors what userspace/driver already configured. Low
regression risk: operations are gated on `ps_int_enabled` and non-
default threshold values. No new APIs, no locking changes beyond clearer
error-path unlock in `write_event_config()`.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: Suspend/resume introduced in `be9e6229d67696` ("iio: light: Add
support for Sensortek STK3310", 2015-04-27). The incomplete PM behavior
has been present since driver introduction. Present in this tree at
lines 671–692.
**Step 3.2 — Fixes: tag**
Record: **N/A** — no `Fixes:` tag.
**Step 3.3 — Related file history**
Record: Recent `stk3310.c` changes in this tree are cleanups
(`7804363d596a8` simplify write_event_config, `a50f537002096` stk3013
support, chip-ID relaxations). No prior fix for this PM interrupt issue.
Fix is **standalone** (patch 1/3 of v4 series; patches 2/3 are style
cleanups only).
**Step 3.4 — Author context**
Record: Miao Li is not a frequent stk3310 contributor in this tree.
Jonathan Cameron (IIO maintainer) Signed-off-by on upstream commit
`9c1d639e90cf4`.
**Step 3.5 — Dependencies**
Record: **None.** Self-contained. Upstream commit `9c1d639e90cf4`
(2026-05-31) applies cleanly to current HEAD (`git apply --check`
succeeded). Not yet in HEAD (`v6.18.44`); present on `autosel` branch as
backport candidate `b0cd7204e0d7f`.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record: `b4 dig -c 9c1d639e90cf4` matched v4 submission:
- https://patch.msgid.link/20260504030408.105762-2-limiao870622@163.com
- Series revisions: v1 (2026-04-27) → v2 → v3 → v4 (2026-05-04, 3-patch
series)
- Applied version is latest v4 patch 1/3
**Step 4.2 — Reviewers**
Record: `b4 dig -w` CC'd Jonathan Cameron (`jic23@kernel.org`), Andy
Shevchenko, linux-iio, linux-kernel. Jonathan Cameron Signed-off-by on
merged commit confirms maintainer acceptance. No explicit stable
nomination found in fetched lore pages (lore.kernel.org blocked by bot
protection; lkml.iu.edu provided patch content only).
**Step 4.3 — Bug report**
Record: Hardware-specific report from author on Inspur HS326 / HiSilicon
M900. No syzbot, bugzilla, or multi-user Reported-by tags. Severity from
reporter: proximity interrupts permanently broken after suspend until
reboot.
**Step 4.4 — Series context**
Record: v4 0/3 cover describes patch 1 as the interrupt fix; patches 2/3
are `uint32_t`→`u32`/padding and `sizeof()` cleanups — **not required**
for the bug fix.
**Step 4.5 — Stable list**
Record: **Not searched successfully** on lore stable list (bot
protection). No evidence found against backport.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `stk3310_suspend()`, `stk3310_resume()`,
`stk3310_write_event()`, `stk3310_write_event_config()`,
`stk3310_init()`, IRQ path `stk3310_irq_event_handler()`.
**Step 5.2 — Callers**
Record:
- `stk3310_suspend/resume` — called via `DEFINE_SIMPLE_DEV_PM_OPS` on
system suspend/resume (common laptop path).
- `stk3310_write_event/write_event_config` — IIO userspace ioctl/event
interface (`stk3310_info` ops table).
- `stk3310_init` — called from `stk3310_probe()` during device
enumeration.
**Step 5.3 — Callees**
Record: `regmap_field_write()`, `regmap_bulk_write()`,
`stk3310_set_state()` — standard regmap/I2C register access, no exotic
dependencies.
**Step 5.4 — Reachability**
Record: Triggered on every system suspend/resume cycle on machines with
STK3310/STK3311 and IRQ wired (`client->irq > 0` in probe). Userspace
proximity event consumers are affected. Not a syscall crash path, but a
common PM path on affected laptops.
**Step 5.5 — Similar patterns**
Record: Other IIO light drivers in this tree implement suspend/resume
state preservation (e.g., `ltr501`, `cm3232`, `al3010`). The stk3310
driver was missing interrupt/threshold restore — an outlier compared to
peers.
---
## Phase 6: Cross-Reference Against Local Tree
**Step 6.1 — Buggy code present?**
Record: **Yes.** Local tree is **Linux 6.18.44** (`git describe HEAD` →
`v6.18.44`). Current `stk3310_suspend()` only calls
`stk3310_set_state(STANDBY)`; `stk3310_resume()` only restores ALS/PS
enable bits. No `ps_int_enabled`/`ps_thdl`/`ps_thdh` fields exist. Bug
present since driver introduction (2015).
**Step 6.2 — Backport complications**
Record: **Clean apply expected.** `git show 9c1d639e90cf4 --
drivers/iio/light/stk3310.c | git apply --check` succeeded on HEAD. No
conflicting recent PM refactors in this file.
**Step 6.3 — Related fixes already present?**
Record: **No.** `git log --grep` found no prior stk3310 PM interrupt fix
in this tree. Grep confirms `ps_int_enabled` absent.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem**
Record: **drivers/iio/light** — IIO ambient-light/proximity sensor
driver. Criticality: **PERIPHERAL** (hardware-specific), but
suspend/resume is a core laptop PM concern for affected machines.
**Step 7.2 — Activity**
Record: IIO light subsystem actively maintained in 6.18.y (recent fixes
for si1133 races, opt3001 timeout, veml6030 events, etc.). stk3310
itself had minor cleanups but no PM fixes.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Users of hardware with STK3310/STK3311/STK3311-X proximity
sensor and IRQ configured — specifically reported on Inspur HS326
(HiSilicon M900). Config-dependent: `CONFIG_STK3310` + device present +
IRQ > 0.
**Step 8.2 — Trigger conditions**
Record: System suspend or hibernation, then resume. **Common** on
laptops. Unprivileged users can trigger via standard PM. Not a race —
deterministic hardware PM bug.
**Step 8.3 — Failure mode severity**
Record: Proximity sensor interrupts stop working after resume; ALS may
still function. No kernel oops, deadlock, or data corruption. Userspace
proximity-dependent features (screen blanking during calls,
lid/proximity policies) break until reboot. **Severity: MEDIUM**
(functional regression on PM path, not CRITICAL crash).
**Step 8.4 — Risk-benefit**
Record:
- **Benefit:** Restores proximity interrupt functionality after suspend
on affected hardware; low user count but 100% reproducible on those
machines.
- **Risk:** Very low — ~70 lines, single driver, gated operations,
maintainer-reviewed.
- **Ratio:** Favorable for stable — classic hardware PM quirk/workaround
pattern.
---
## Phase 9: Final Synthesis
**Step 9.1 — Evidence summary**
**FOR backport:**
- Real, reproducible hardware bug on production laptop (Inspur HS326)
- Suspend/resume PM quirk — established stable category
- Small, self-contained, maintainer Signed-off-by
- Driver and buggy code exist in 6.18.44 since 2015
- Applies cleanly to this tree
- Standalone (no series dependencies)
**AGAINST backport:**
- Not crash/security/corruption/deadlock
- Narrow hardware scope (STK3311-X on specific platforms)
- Long-standing bug (not a recent regression)
- No syzbot or multi-user reports
**Unresolved:** No explicit `Cc: stable` or reviewer stable nomination
found; full lore review thread not readable due to bot protection.
**Step 9.2 — Stable rules checklist**
| Criterion | Result |
|-----------|--------|
| 1. Obviously correct and tested? | **PASS** — clear PM sequence,
maintainer SOB, hardware-verified |
| 2. Fixes real bug affecting users? | **PASS** — proximity interrupts
broken after suspend on real hardware |
| 3. Important issue? | **PASS (borderline)** — functional PM regression
on laptops, not crash-level |
| 4. Small and contained? | **PASS** — one file, ~76 lines |
| 5. No new features/APIs? | **PASS** — internal state tracking for
existing functionality |
| 6. Applies to local tree? | **PASS** — verified clean apply to 6.18.44
|
**Step 9.3 — Exception category**
Record: **Hardware quirk/workaround** for suspend/resume on STK3311-X —
fits the stable exception for device-specific PM workarounds.
**Step 9.4 — Decision rationale**
This commit fixes a real suspend/resume hardware interaction bug in a
driver that has been in stable kernels since v4.1. While the failure
mode is functional rather than a kernel crash, proximity sensor
interrupts are user-visible and the bug triggers on every suspend cycle
on affected laptops. The fix is small, maintainer-approved, applies
cleanly to Linux 6.18.44, and follows the established pattern of
backporting driver PM quirks for real hardware.
---
## Verification
- [Phase 1] Parsed commit message and tags from user-provided diff and
`git show 9c1d639e90cf4`
- [Phase 2] Diff analysis: 1 file, 5 functions, PM state-tracking +
suspend/resume sequence
- [Phase 3] `git blame -L 671,692`: suspend/resume from `be9e6229d67696`
(2015-04-27)
- [Phase 3] `git log --oneline -20 -- drivers/iio/light/stk3310.c`: no
prior PM interrupt fix
- [Phase 3] `git show 9c1d639e90cf4`: upstream commit dated 2026-05-31,
Jonathan Cameron SOB
- [Phase 3] `git merge-base --is-ancestor b0cd7204e0d7f HEAD` → not
ancestor; fix not in HEAD
- [Phase 4] `b4 dig -c 9c1d639e90cf4`: lore URL found, v1–v4 revisions
- [Phase 4] `b4 dig -c 9c1d639e90cf4 -w`: jic23@kernel.org CC'd
- [Phase 4] `b4 dig -c 9c1d639e90cf4 -a`: v4 is latest, patch 1/3 is the
fix
- [Phase 4] lkml.iu.edu: fetched v4 cover and patch 1/3 content
- [Phase 5] Read `stk3310.c`: PM ops, IRQ probe path, IIO event ops
confirmed
- [Phase 5] `iio_device_alloc()` uses `kzalloc()` — `ps_thdl` defaults
to 0 verified
- [Phase 6] `git describe HEAD` → v6.18.44; `make kernelversion` →
6.18.44
- [Phase 6] Grep: no `ps_int_enabled` in current tree — buggy code
present, fix absent
- [Phase 6] `git show 9c1d639e90cf4 -- drivers/iio/light/stk3310.c | git
apply --check` → clean apply
- [Phase 8] Failure mode: proximity interrupts dead after resume,
severity MEDIUM
- UNVERIFIED: Full lore review thread replies (bot protection on
lore.kernel.org/patch.msgid.link)
- UNVERIFIED: Whether Jonathan Cameron explicitly nominated for stable
in list replies
**YES**
drivers/iio/light/stk3310.c | 76 +++++++++++++++++++++++++++++++++----
1 file changed, 69 insertions(+), 7 deletions(-)
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index a75a83594a7ee..3be6934218866 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -117,6 +117,9 @@ struct stk3310_data {
struct mutex lock;
bool als_enabled;
bool ps_enabled;
+ bool ps_int_enabled;
+ uint32_t ps_thdl;
+ uint32_t ps_thdh;
uint32_t ps_near_level;
u64 timestamp;
struct regmap *regmap;
@@ -296,10 +299,17 @@ static int stk3310_write_event(struct iio_dev *indio_dev,
buf = cpu_to_be16(val);
ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set PS threshold!\n");
+ return ret;
+ }
- return ret;
+ if (reg == STK3310_REG_THDH_PS)
+ data->ps_thdh = val;
+ else
+ data->ps_thdl = val;
+
+ return 0;
}
static int stk3310_read_event_config(struct iio_dev *indio_dev,
@@ -331,11 +341,17 @@ static int stk3310_write_event_config(struct iio_dev *indio_dev,
/* Set INT_PS value */
mutex_lock(&data->lock);
ret = regmap_field_write(data->reg_int_ps, state);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to set interrupt mode\n");
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->ps_int_enabled = state;
+
mutex_unlock(&data->lock);
- return ret;
+ return 0;
}
static int stk3310_read_raw(struct iio_dev *indio_dev,
@@ -504,10 +520,15 @@ static int stk3310_init(struct iio_dev *indio_dev)
/* Enable PS interrupts */
ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "failed to enable interrupts!\n");
+ return ret;
+ }
- return ret;
+ data->ps_int_enabled = true;
+ data->ps_thdh = STK3310_PS_MAX_VAL;
+
+ return 0;
}
static bool stk3310_is_volatile_reg(struct device *dev, unsigned int reg)
@@ -671,9 +692,18 @@ static void stk3310_remove(struct i2c_client *client)
static int stk3310_suspend(struct device *dev)
{
struct stk3310_data *data;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, 0x0);
+ if (ret < 0) {
+ dev_err(dev, "failed to disable ps int at suspend.\n");
+ return ret;
+ }
+ }
+
return stk3310_set_state(data, STK3310_STATE_STANDBY);
}
@@ -681,6 +711,8 @@ static int stk3310_resume(struct device *dev)
{
u8 state = 0;
struct stk3310_data *data;
+ __be16 buf;
+ int ret;
data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
if (data->ps_enabled)
@@ -688,7 +720,37 @@ static int stk3310_resume(struct device *dev)
if (data->als_enabled)
state |= STK3310_STATE_EN_ALS;
- return stk3310_set_state(data, state);
+ ret = stk3310_set_state(data, state);
+ if (ret < 0)
+ return ret;
+
+ if (data->ps_thdl != 0x0) {
+ buf = cpu_to_be16(data->ps_thdl);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDL_PS, &buf, 2);
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDL_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_thdh != STK3310_PS_MAX_VAL) {
+ buf = cpu_to_be16(data->ps_thdh);
+ ret = regmap_bulk_write(data->regmap, STK3310_REG_THDH_PS, &buf, 2);
+ if (ret < 0) {
+ dev_err(dev, "failed to set reg THDH_PS at resume.\n");
+ return ret;
+ }
+ }
+
+ if (data->ps_int_enabled) {
+ ret = regmap_field_write(data->reg_int_ps, STK3310_PSINT_EN);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable ps int at resume.\n");
+ return ret;
+ }
+ }
+
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend,
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 6.18-6.12] iio: adc: rtq6056: add i2c_device_id support
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-5.10] iio: accel: mma8452: switch to non-devm request_threaded_irq() Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.1] iio: light: stk3310: Deal with the ps interrupt issue in PM Sasha Levin
@ 2026-08-31 13:25 ` Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.10] iio: adc: qcom-spmi-iadc: balance enable_irq_wake() on driver unbind Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-31 13:25 UTC (permalink / raw)
To: patches, stable
Cc: Kevin Tung, Andy Shevchenko, Jonathan Cameron, Sasha Levin,
linux-iio, linux-kernel
From: Kevin Tung <kevin.tung.openbmc@gmail.com>
[ Upstream commit ce80292ead5bb42b50a6b63e44fd95c0edf9d334 ]
Add i2c_device_id table to support legacy I2C instantiation.
Update probe to use i2c_get_match_data() so device data can be
retrieved consistently for both OF and legacy I2C instantiation.
Signed-off-by: Kevin Tung <kevin.tung.openbmc@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
The background branch search finished (~79s). It didn’t turn up anything
useful for this commit: `git log -S "rtq6056_probe" --remotes` returned
unrelated picks from large `linux-next` merges, and the `master` search
only hit an unrelated merge touching that file.
That doesn’t change the earlier conclusion for **6.18.43**: the
regression is present in the current tree, the fix is small and well-
reviewed, and the backport recommendation remains **YES**.
drivers/iio/adc/rtq6056.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/rtq6056.c b/drivers/iio/adc/rtq6056.c
index 2bf3a09ac6b04..e2b1da13c0d31 100644
--- a/drivers/iio/adc/rtq6056.c
+++ b/drivers/iio/adc/rtq6056.c
@@ -728,7 +728,7 @@ static int rtq6056_probe(struct i2c_client *i2c)
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -EOPNOTSUPP;
- devdata = device_get_match_data(dev);
+ devdata = i2c_get_match_data(i2c);
if (!devdata)
return dev_err_probe(dev, -EINVAL, "Invalid dev data\n");
@@ -871,6 +871,13 @@ static const struct richtek_dev_data rtq6059_devdata = {
.set_average = rtq6059_adc_set_average,
};
+static const struct i2c_device_id rtq6056_id[] = {
+ { "rtq6056", (kernel_ulong_t)&rtq6056_devdata },
+ { "rtq6059", (kernel_ulong_t)&rtq6059_devdata },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rtq6056_id);
+
static const struct of_device_id rtq6056_device_match[] = {
{ .compatible = "richtek,rtq6056", .data = &rtq6056_devdata },
{ .compatible = "richtek,rtq6059", .data = &rtq6059_devdata },
@@ -885,6 +892,7 @@ static struct i2c_driver rtq6056_driver = {
.pm = pm_ptr(&rtq6056_pm_ops),
},
.probe = rtq6056_probe,
+ .id_table = rtq6056_id,
};
module_i2c_driver(rtq6056_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] iio: adc: qcom-spmi-iadc: balance enable_irq_wake() on driver unbind
[not found] <20260831133314.4125787-1-sashal@kernel.org>
` (2 preceding siblings ...)
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] iio: adc: rtq6056: add i2c_device_id support Sasha Levin
@ 2026-08-31 13:27 ` Sasha Levin
3 siblings, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-31 13:27 UTC (permalink / raw)
To: patches, stable
Cc: Stepan Ionichev, Jonathan Cameron, Sasha Levin, linux-arm-msm,
linux-iio, linux-kernel
From: Stepan Ionichev <sozdayvek@gmail.com>
[ Upstream commit 929fec2964f71d4b1ac664ee963d8226c5cf01c6 ]
iadc_probe() calls enable_irq_wake() after a successful
devm_request_irq(), but the driver has no remove callback or
matching disable_irq_wake(), so the wake reference count on the
IRQ is leaked on module unload or driver unbind.
Check the IRQ request error first, then register a devm action
that calls disable_irq_wake() so the wake reference is released
in the same scope as the enable. While here, drop the inverted
"if (!ret) ... else return ret" in favour of the standard
"if (ret) return ret;" pattern.
Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: `iio: adc: qcom-spmi-iadc: balance
enable_irq_wake() on driver unbind`
**Local tree:** Linux **6.18.44** (`git describe HEAD` → `v6.18.44`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject line
**Record:** `[iio: adc: qcom-spmi-iadc]` `[balance]` — fix unbalanced
`enable_irq_wake()` / missing `disable_irq_wake()` on driver teardown.
### Step 1.2: Tags
**Record:**
- **Signed-off-by:** Stepan Ionichev `<sozdayvek@gmail.com>` (author)
- **Signed-off-by:** Jonathan Cameron `<jic23@kernel.org>` (IIO
maintainer, committer)
- **Fixes:** `ce0694841ea6` (in v3 submission; absent from user-provided
message but verified in lore v3)
- No Reported-by, Tested-by, Cc: stable, or Link: tags in provided
message
- Notable: v3 lore thread has **Reviewed-by: Konrad Dybcio** (Qualcomm)
### Step 1.3: Body analysis
**Record:**
- **Bug:** `iadc_probe()` calls `enable_irq_wake()` after successful
`devm_request_irq()`, but there is no `.remove` callback and no
matching `disable_irq_wake()`.
- **Symptom:** IRQ `wake_depth` reference count is leaked on module
unload or driver unbind.
- **Root cause:** Asymmetric IRQ wake enable/disable lifecycle.
- **Fix approach:** Register `devm_add_action_or_reset()` to call
`disable_irq_wake()` at device teardown; also check
`enable_irq_wake()` return value and normalize error-handling style.
### Step 1.4: Hidden bug fix?
**Record:** No — this is an explicit resource-leak / PM lifecycle bug
fix, not disguised cleanup.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `drivers/iio/adc/qcom-spmi-iadc.c` (+15 / -3 lines)
- **Functions:** new `iadc_disable_irq_wake()`, modified `iadc_probe()`
- **Scope:** Single-file, surgical driver fix
### Step 2.2: Code flow change
**Record:**
- **Hunk 1 (new helper):** Adds `iadc_disable_irq_wake()` that calls
`disable_irq_wake((unsigned long)data)`.
- **Hunk 2 (probe IRQ path):**
- **Before:** `devm_request_irq()` → on success call
`enable_irq_wake()` (return value ignored); on failure return.
- **After:** `devm_request_irq()` → return on error →
`enable_irq_wake()` with error check →
`devm_add_action_or_reset(iadc_disable_irq_wake)` with error check.
- **After:** `disable_irq_wake()` runs automatically when the device
is released (unbind/remove), balancing the earlier
`enable_irq_wake()`.
### Step 2.3: Bug mechanism
**Record:** **Category:** Resource leak / reference-counting (IRQ wake
depth).
- `enable_irq_wake()` → `irq_set_irq_wake(irq, 1)` increments
`desc->wake_depth` (see `kernel/irq/manage.c:872`).
- Without matching `disable_irq_wake()`, `wake_depth` never returns to
zero on unbind.
- IRQ remains in `IRQD_WAKEUP_STATE`; repeated probe/unbind cycles can
accumulate `wake_depth`.
### Step 2.4: Fix quality
**Record:** Obviously correct; mirrors established pattern in
`drivers/rtc/rtc-isl1208.c` (`isl1208_disable_irq_wake_action` +
`devm_add_action_or_reset`). Minimal regression risk. Slight behavior
change: `enable_irq_wake()` failure now fails probe (old code ignored
its return value); reviewers confirmed this is acceptable for QC SPMI
platforms.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** `enable_irq_wake(irq_eoc)` at line 542 in local tree. `git
show ce0694841ea6` confirms `enable_irq_wake` was present in the
original 2014 driver import — bug present since driver introduction.
### Step 3.2: Fixes: tag
**Record:** `Fixes: ce0694841ea6` ("iio: iadc: Qualcomm SPMI PMIC
current ADC driver", Oct 2014). That commit exists in this tree; driver
and buggy `enable_irq_wake` call are present.
### Step 3.3: Related file history
**Record:** Autosel checkout has flattened history (`git log --
drivers/iio/adc/qcom-spmi-iadc.c` shows only one unrelated commit). File
content verified directly. No evidence of a prior fix for this issue in
the tree.
### Step 3.4: Author context
**Record:** Stepan Ionichev submitted multiple IIO driver fixes in 2026.
Jonathan Cameron (IIO maintainer) reviewed and merged. Konrad Dybcio
(Qualcomm) reviewed v3.
### Step 3.5: Dependencies
**Record:** Standalone. Uses `devm_add_action_or_reset()` (available in
`include/linux/device/devres.h` in this tree). No series dependencies.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original discussion
**Record:**
- v1: https://lkml.iu.edu/2605.2/09223.html (May 20, 2026)
- v3 review: https://lists.openwall.net/linux-kernel/2026/07/06/2032
- Jonathan Cameron reviewed v1 (May 26, 2026); v3 got Reviewed-by from
Konrad Dybcio
- Merged via Jonathan Cameron's 7.2-rc1 IIO pull (June 22, 2026)
- No explicit stable nomination found in fetched threads
### Step 4.2: Reviewers
**Record:** Jonathan Cameron (IIO maintainer), Konrad Dybcio (Qualcomm),
CC'd linux-iio, linux-arm-msm.
### Step 4.3: Bug reports
**Record:** No syzbot or user crash reports. Bug identified via code
review / static lifecycle analysis.
### Step 4.4: Series context
**Record:** v1 → v3 revisions; cast style adjusted per maintainer
feedback. Final committed version matches v3.
### Step 4.5: Stable list
**Record:** No stable-list discussion found (not searched exhaustively
due to lore access limits).
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key functions
**Record:** `iadc_disable_irq_wake()` (new), `iadc_probe()` (modified),
`iadc_isr()` (unchanged, IRQ handler).
### Step 5.2: Callers
**Record:** `iadc_probe()` registered as `.probe` in `iadc_driver`
platform driver; invoked during device enumeration on `qcom,spmi-iadc`
compatible nodes. `iadc_isr()` called from IRQ context during ADC
conversions.
### Step 5.3: Callees
**Record:** `devm_request_irq()`, `enable_irq_wake()`,
`devm_add_action_or_reset()`, `disable_irq_wake()` (via devm action on
teardown).
### Step 5.4: Reachability
**Record:** Probe runs at boot on Qualcomm SPMI PMIC platforms. Leak
triggers on driver unbind (`rmmod` if modular) or device rebinding —
uncommon in production but real in development/testing and modular
builds.
### Step 5.5: Similar patterns
**Record:** Identical devm pattern in `rtc-isl1208.c`. Other IIO drivers
(e.g. `st_lsm6dsx`) balance enable/disable via suspend/resume PM ops;
this driver has no PM ops, making devm action the correct approach.
---
## PHASE 6: CROSS-REFERENCING AGAINST LOCAL TREE (6.18.44)
### Step 6.1: Buggy code present?
**Record:** **Yes.** Current tree at `drivers/iio/adc/qcom-spmi-
iadc.c:538-544`:
```538:544:drivers/iio/adc/qcom-spmi-iadc.c
if (!iadc->poll_eoc) {
ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0,
"spmi-iadc", iadc);
if (!ret)
enable_irq_wake(irq_eoc);
else
return ret;
```
No `iadc_disable_irq_wake()` or `devm_add_action_or_reset()` present.
Bug has existed since driver introduction (2014).
### Step 6.2: Backport complications
**Record:** Clean apply expected — local file matches the diff's
"before" state exactly. No conflicting changes detected.
### Step 6.3: Related fixes already present?
**Record:** None found.
---
## PHASE 7: SUBSYSTEM CONTEXT
### Step 7.1: Subsystem criticality
**Record:** **drivers/iio/adc** — IMPORTANT for Qualcomm
ARM/embedded/mobile platforms using SPMI PMIC current sensing. Not core-
kernel-wide, but affects real hardware users.
### Step 7.2: Activity
**Record:** Driver is mature (2014); recent fix is lifecycle
correctness, not new functionality.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who is affected
**Record:** Users of `qcom,spmi-iadc` on Qualcomm platforms (phones,
tablets, embedded) where the IRQ (non-polling) path is used.
### Step 8.2: Trigger conditions
**Record:** Driver probe with valid IRQ, then driver unbind/module
unload. Uncommon in typical built-in deployments; more relevant for
modular builds, driver rebinding, or test harnesses. Not userspace-
triggerable for unprivileged crash.
### Step 8.3: Failure mode severity
**Record:** IRQ wake reference leak → `wake_depth` stuck elevated,
`IRQD_WAKEUP_STATE` may persist incorrectly, possible accumulation on
re-probe. **Severity: MEDIUM** — PM/wakeup correctness issue, not a
direct crash or data corruption, but a real kernel resource leak with
long-standing presence.
### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** Correct IRQ wake lifecycle; prevents refcount leak and
incorrect wakeup state on teardown/re-probe.
- **Risk:** Very low — ~15 lines, established devm pattern, maintainer +
Qualcomm review.
- **Ratio:** Moderate benefit, very low risk → favorable for stable.
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence summary
**FOR backport:**
- Real, verified resource leak (`wake_depth` refcount)
- Bug present since 2014 in this tree
- Small, surgical, obviously correct fix
- IIO maintainer + Qualcomm reviewer endorsement
- Matches in-tree precedent (`rtc-isl1208.c`)
- Also improves ignored `enable_irq_wake()` error handling
**AGAINST backport:**
- Only manifests on driver unbind (rare in production built-in use)
- No crash reports or syzbot findings
- Severity is PM correctness, not crash/corruption
**Unresolved:** No explicit stable nomination in lore; no runtime crash
reports.
### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — logic verified against
`irq_set_irq_wake()` refcount semantics; maintainer-reviewed.
2. Fixes a real bug? **PASS** — unbalanced IRQ wake enable/disable.
3. Important issue? **PASS (moderate)** — PM/wakeup refcount leak with
accumulation potential; fits stable resource-leak category.
4. Small and contained? **PASS** — 1 file, ~18 lines.
5. No new features/APIs? **PASS** — lifecycle fix only.
6. Can apply to local tree? **PASS** — buggy code confirmed present;
clean apply expected.
### Step 9.3: Exception categories
**Record:** None (not device ID, quirk, DT, build, or docs fix).
### Step 9.4: Decision rationale
For **Linux 6.18.44**, the `qcom-spmi-iadc` driver contains the long-
standing unbalanced `enable_irq_wake()` call. The fix is minimal,
follows an established devm pattern already used elsewhere in this tree,
and corrects a real IRQ wake refcount leak on driver teardown. While the
trigger is infrequent in typical built-in deployments, the bug has been
present since 2014, can affect suspend/wakeup state, and can accumulate
across re-probes. This is appropriate stable material for a conservative
driver lifecycle fix.
---
## Verification
- **[Phase 1]** Parsed subject, tags, body from user query; cross-
checked v3 lore for Fixes:/Reviewed-by
- **[Phase 2]** Diff analyzed; read `kernel/irq/manage.c:857-893` for
`wake_depth` refcount semantics
- **[Phase 2]** Compared with `drivers/rtc/rtc-isl1208.c:825-847` —
identical devm pattern
- **[Phase 3]** `git describe HEAD` → v6.18.44; `make kernelversion` →
6.18.44
- **[Phase 3]** `git show ce0694841ea6` — original 2014 driver commit
exists; contains `enable_irq_wake`
- **[Phase 3]** `git blame` on lines 530-560 — buggy code present
(history flattened in autosel repo)
- **[Phase 4]** Web search + WebFetch of lkml/openwall threads — v1/v3
discussion, Jonathan Cameron + Konrad Dybcio review
- **[Phase 4]** b4 dig -c HEAD failed (commit not in tree) — used web
sources instead
- **[Phase 5]** Read `iadc_probe()`, `iadc_isr()`, platform driver
registration
- **[Phase 6]** Grep confirmed buggy `enable_irq_wake` without matching
disable in local tree
- **[Phase 6]** Grep confirmed `devm_add_action_or_reset` available in
`include/linux/device/devres.h`
- **[Phase 6]** No prior fix for this issue found in tree
- **[Phase 8]** Assessed trigger (unbind) and severity (MEDIUM PM leak)
**YES**
drivers/iio/adc/qcom-spmi-iadc.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c
index b64a8a407168b..0ec3a0c4b1de0 100644
--- a/drivers/iio/adc/qcom-spmi-iadc.c
+++ b/drivers/iio/adc/qcom-spmi-iadc.c
@@ -481,6 +481,11 @@ static const struct iio_chan_spec iadc_channels[] = {
},
};
+static void iadc_disable_irq_wake(void *data)
+{
+ disable_irq_wake((unsigned long)data);
+}
+
static int iadc_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -538,9 +543,16 @@ static int iadc_probe(struct platform_device *pdev)
if (!iadc->poll_eoc) {
ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0,
"spmi-iadc", iadc);
- if (!ret)
- enable_irq_wake(irq_eoc);
- else
+ if (ret)
+ return ret;
+
+ ret = enable_irq_wake(irq_eoc);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, iadc_disable_irq_wake,
+ (void *)(unsigned long)irq_eoc);
+ if (ret)
return ret;
} else {
ret = devm_device_init_wakeup(iadc->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-31 13:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260831133314.4125787-1-sashal@kernel.org>
2026-08-31 13:21 ` [PATCH AUTOSEL 6.18-5.10] iio: accel: mma8452: switch to non-devm request_threaded_irq() Sasha Levin
2026-08-31 13:23 ` [PATCH AUTOSEL 6.18-6.1] iio: light: stk3310: Deal with the ps interrupt issue in PM Sasha Levin
2026-08-31 13:25 ` [PATCH AUTOSEL 6.18-6.12] iio: adc: rtq6056: add i2c_device_id support Sasha Levin
2026-08-31 13:27 ` [PATCH AUTOSEL 6.18-5.10] iio: adc: qcom-spmi-iadc: balance enable_irq_wake() on driver unbind Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox