mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Myeonghun Pak <mhun512@gmail.com>
To: Sebastian Reichel <sre@kernel.org>
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
	Ijae Kim <ae878000@gmail.com>
Subject: [PATCH] HSI: nokia-modem: stop reset IRQ before killing tasklet
Date: Sat,  3 Oct 2026 00:23:27 -0400	[thread overview]
Message-ID: <20261003042327.655834-1-mhun512@gmail.com> (raw)

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


                 reply	other threads:[~2026-10-03  4:23 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20261003042327.655834-1-mhun512@gmail.com \
    --to=mhun512@gmail.com \
    --cc=ae878000@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sre@kernel.org \
    --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

all inboxes | Powered by JetHome®