[RFC PATCH 1/2] ASoC: cs42l42: handle jack interrupt I/O and resume errors

From: Ryan Murray

Date: Thu Sep 17 2026 - 03:24:17 EST


A failed status or mask read leaves part of the interrupt snapshot
uninitialized. The handler can then interpret that data as headset or
button events. It also attempts register access after a failed runtime
resume.

Check the runtime-PM acquisition and each snapshot read before processing
any events. Use the transparent autosuspend guard so the always-powered
I2C transport continues to work when runtime PM is disabled. Keep the
existing scoped mutex and PM cleanup on every return path.

An extracted-handler fault-injection test reproduces event processing on
failed reads before this change and checks all 24 snapshot read failures
after it, together with resume failure and disabled-runtime-PM cases.

Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Assisted-by: LLM
Signed-off-by: Ryan Murray <ryan@xxxxxxxxxxxxxxxxx>
---
sound/soc/codecs/cs42l42.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index fadf68860..2d1b45ea1 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -1667,18 +1667,25 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data)
unsigned int current_plug_status;
unsigned int current_button_status;
unsigned int i;
+ int ret;

- guard(pm_runtime_active_auto)(cs42l42->dev);
+ PM_RUNTIME_ACQUIRE_AUTOSUSPEND(cs42l42->dev, pm);
+ if (PM_RUNTIME_ACQUIRE_ERR(&pm))
+ return IRQ_NONE;
guard(mutex)(&cs42l42->irq_lock);
if (cs42l42->suspended || !cs42l42->init_done)
return IRQ_NONE;

- /* Read sticky registers to clear interurpt */
+ /* Read sticky registers to clear interrupt */
for (i = 0; i < ARRAY_SIZE(stickies); i++) {
- regmap_read(cs42l42->regmap, irq_params_table[i].status_addr,
- &(stickies[i]));
- regmap_read(cs42l42->regmap, irq_params_table[i].mask_addr,
- &(masks[i]));
+ ret = regmap_read(cs42l42->regmap, irq_params_table[i].status_addr,
+ &stickies[i]);
+ if (ret)
+ goto out_error;
+ ret = regmap_read(cs42l42->regmap, irq_params_table[i].mask_addr,
+ &masks[i]);
+ if (ret)
+ goto out_error;
stickies[i] = stickies[i] & (~masks[i]) &
irq_params_table[i].mask;
}
@@ -1772,6 +1779,10 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data)
}

return IRQ_HANDLED;
+
+out_error:
+ dev_err_ratelimited(cs42l42->dev, "Failed to read jack interrupt state: %d\n", ret);
+ return IRQ_NONE;
}
EXPORT_SYMBOL_NS_GPL(cs42l42_irq_thread, "SND_SOC_CS42L42_CORE");