Thread (3 messages) flat view 3 messages, 1 author, 3d ago
WARM3d

[PATCH net v3 2/2] nfc: trf7970a: quiesce timeout work before teardown

From: Fan Wu <hidden>
Date: 2026-08-01 05:11:58
Also in: lkml, netdev, oe-linux-nfc, stable
Subsystem: nfc subsystem, the rest, ti trf7970a nfc driver · Maintainers: David Heidelberg, Linus Torvalds, Mark Greer

The timeout work can be running, blocked on trf->lock, while
trf7970a_remove() runs trf7970a_shutdown() under that lock. shutdown()
completes the active command through trf->cb(), but its non-blocking
cancel cannot stop a handler that is already running. Once remove drops
the lock, the handler may resume and complete the same command a second
time through trf->cb(). By then nfc_digital_unregister_device() may have
freed the struct digital_cmd referenced by trf->cb_arg.

Set ignore_timeout before shutdown completes the command, so the handler
short-circuits when it resumes. Then call cancel_delayed_work_sync()
after nfc_digital_unregister_device() and before nfc_digital_free_device().

Handle TRF7970A_ST_LISTENING_MD in shutdown so RF is switched off for
that state too; otherwise a threaded IRQ can re-arm the work after the
drain.

This patch depends on the preceding patch, which keeps trf->lock valid
until the threaded IRQ is drained.

This issue was found by an in-house static analysis tool.

Fixes: 165063f1dac4 ("NFC: trf7970a: Add driver with ISO/IEC 14443 Type 2 Tag Support")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <redacted>
---
 drivers/nfc/trf7970a.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 9c6f8db..42e7c05 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -2015,6 +2015,8 @@ static void trf7970a_shutdown(struct trf7970a *trf)
 	case TRF7970A_ST_WAIT_FOR_RX_DATA_CONT:
 	case TRF7970A_ST_WAIT_TO_ISSUE_EOF:
 	case TRF7970A_ST_LISTENING:
+	case TRF7970A_ST_LISTENING_MD:
+		trf->ignore_timeout = true;
 		trf7970a_send_err_upstream(trf, -ECANCELED);
 		fallthrough;
 	case TRF7970A_ST_IDLE:
@@ -2210,6 +2212,7 @@ static int trf7970a_probe(struct spi_device *spi)
 err_shutdown:
 	trf7970a_shutdown(trf);
 err_free_ddev:
+	cancel_delayed_work_sync(&trf->timeout_work);
 	nfc_digital_free_device(trf->ddev);
 err_disable_vddio_regulator:
 	regulator_disable(trf->vddio_regulator);
@@ -2229,6 +2232,7 @@ static void trf7970a_remove(struct spi_device *spi)
 	mutex_unlock(&trf->lock);
 
 	nfc_digital_unregister_device(trf->ddev);
+	cancel_delayed_work_sync(&trf->timeout_work);
 	nfc_digital_free_device(trf->ddev);
 
 	regulator_disable(trf->vddio_regulator);
-- 
2.34.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help