* [PATCH] HSI: nokia-modem: stop reset IRQ before killing tasklet
@ 2026-10-03 4:23 Myeonghun Pak
0 siblings, 0 replies; only message in thread
From: Myeonghun Pak @ 2026-10-03 4:23 UTC (permalink / raw)
To: Sebastian Reichel; +Cc: linux-kernel, stable, Ijae Kim
The reset IRQ schedules a tasklet which accesses both the modem and its
SSI protocol client. Disabling IRQ wake does not disable the IRQ, and the
managed IRQ remains registered until after the remove callback or probe
failure cleanup has returned. It can therefore schedule the tasklet again
after tasklet_kill(), leaving it pending when the modem is freed. The
existing cleanup also unregisters the SSI client before draining the
tasklet that uses it.
Explicitly release the managed IRQ before killing the tasklet, and do both
before unregistering the child clients. Use a common post-IRQ probe error
path so every failure drains the tasklet before releasing its dependencies.
Track successful GPIO exports to retain the existing partial-probe cleanup
behavior.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: eafaebd987fc ("HSI: Introduce Nokia N900 modem driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
---
drivers/hsi/clients/nokia-modem.c | 38 ++++++++++++++++++-------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/hsi/clients/nokia-modem.c b/drivers/hsi/clients/nokia-modem.c
index 88924d757616..688ce742d358 100644
--- a/drivers/hsi/clients/nokia-modem.c
+++ b/drivers/hsi/clients/nokia-modem.c
@@ -131,6 +131,7 @@ static int nokia_modem_probe(struct device *dev)
int irq, pflags, err;
struct hsi_board_info ssip;
struct hsi_board_info cmtspeech;
+ bool gpios_exported = false;
np = dev->of_node;
if (!np) {
@@ -165,8 +166,9 @@ static int nokia_modem_probe(struct device *dev)
err = nokia_modem_gpio_probe(dev);
if (err < 0) {
dev_err(dev, "Could not probe GPIOs\n");
- goto error1;
+ goto error;
}
+ gpios_exported = true;
}
ssip.name = "ssi-protocol";
@@ -179,17 +181,17 @@ static int nokia_modem_probe(struct device *dev)
if (!modem->ssi_protocol) {
dev_err(dev, "Could not register ssi-protocol device\n");
err = -ENOMEM;
- goto error2;
+ goto error;
}
err = device_attach(&modem->ssi_protocol->device);
if (err == 0) {
dev_dbg(dev, "Missing ssi-protocol driver\n");
err = -EPROBE_DEFER;
- goto error3;
+ goto error;
} else if (err < 0) {
dev_err(dev, "Could not load ssi-protocol driver (%d)\n", err);
- goto error3;
+ goto error;
}
cmtspeech.name = "cmt-speech";
@@ -202,33 +204,35 @@ static int nokia_modem_probe(struct device *dev)
if (!modem->cmt_speech) {
dev_err(dev, "Could not register cmt-speech device\n");
err = -ENOMEM;
- goto error3;
+ goto error;
}
err = device_attach(&modem->cmt_speech->device);
if (err == 0) {
dev_dbg(dev, "Missing cmt-speech driver\n");
err = -EPROBE_DEFER;
- goto error4;
+ goto error;
} else if (err < 0) {
dev_err(dev, "Could not load cmt-speech driver (%d)\n", err);
- goto error4;
+ goto error;
}
dev_info(dev, "Registered Nokia HSI modem\n");
return 0;
-error4:
- hsi_remove_client(&modem->cmt_speech->device, NULL);
-error3:
- hsi_remove_client(&modem->ssi_protocol->device, NULL);
-error2:
- nokia_modem_gpio_unexport(dev);
-error1:
+error:
disable_irq_wake(modem->nokia_modem_rst_ind_irq);
+ devm_free_irq(dev, modem->nokia_modem_rst_ind_irq, modem);
tasklet_kill(&modem->nokia_modem_rst_ind_tasklet);
+ if (modem->cmt_speech)
+ hsi_remove_client(&modem->cmt_speech->device, NULL);
+ if (modem->ssi_protocol)
+ hsi_remove_client(&modem->ssi_protocol->device, NULL);
+ if (gpios_exported)
+ nokia_modem_gpio_unexport(dev);
+
return err;
}
@@ -239,6 +243,10 @@ static int nokia_modem_remove(struct device *dev)
if (!modem)
return 0;
+ disable_irq_wake(modem->nokia_modem_rst_ind_irq);
+ devm_free_irq(dev, modem->nokia_modem_rst_ind_irq, modem);
+ tasklet_kill(&modem->nokia_modem_rst_ind_tasklet);
+
if (modem->cmt_speech) {
hsi_remove_client(&modem->cmt_speech->device, NULL);
modem->cmt_speech = NULL;
@@ -251,8 +259,6 @@ static int nokia_modem_remove(struct device *dev)
nokia_modem_gpio_unexport(dev);
dev_set_drvdata(dev, NULL);
- disable_irq_wake(modem->nokia_modem_rst_ind_irq);
- tasklet_kill(&modem->nokia_modem_rst_ind_tasklet);
return 0;
}
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-03 4:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-03 4:23 [PATCH] HSI: nokia-modem: stop reset IRQ before killing tasklet Myeonghun Pak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®