[PATCH net] nfc: trf7970a: drain timeout_work and keep trf->lock valid across teardown

Fan Wu posted 1 patch 3 days, 10 hours ago
drivers/nfc/trf7970a.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
[PATCH net] nfc: trf7970a: drain timeout_work and keep trf->lock valid across teardown
Posted by Fan Wu 3 days, 10 hours ago
The threaded IRQ handler and timeout work can wait on trf->lock while
teardown destroys it. The timeout handler can also access the digital
device after it has been freed.

Synchronize timeout_work before releasing the digital device, and leave
the embedded mutex alive for devres cleanup to synchronize the IRQ
handler before trf is freed: devm_request_threaded_irq() is registered
after devm_kzalloc(), so devm_free_irq() runs before trf is released.

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 <fanwu01@zju.edu.cn>
---
 drivers/nfc/trf7970a.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index d17c701..fa2f75a 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -2206,13 +2206,13 @@ 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);
 err_disable_vin_regulator:
 	regulator_disable(trf->vin_regulator);
 err_destroy_lock:
-	mutex_destroy(&trf->lock);
 	return ret;
 }
 
@@ -2226,13 +2226,13 @@ static void trf7970a_remove(struct spi_device *spi)
 
 	mutex_unlock(&trf->lock);
 
+	cancel_delayed_work_sync(&trf->timeout_work);
+
 	nfc_digital_unregister_device(trf->ddev);
 	nfc_digital_free_device(trf->ddev);
 
 	regulator_disable(trf->vddio_regulator);
 	regulator_disable(trf->vin_regulator);
-
-	mutex_destroy(&trf->lock);
 }
 
 #ifdef CONFIG_PM_SLEEP
-- 
2.34.1