From 7754a2924604ea442ef03ed8fc12ccc9221a2e98 Mon Sep 17 00:00:00 2001 From: Runyu Xiao Date: Tue, 29 Sep 2026 21:22:45 +0800 Subject: [PATCH] mei: vsc-tp: initialize IRQ state before requesting interrupt request_threaded_irq() enables the interrupt before returning, so the threaded handler may schedule work while the probe is still initializing its mutexes and work item. Initialize that state first and only free the IRQ on paths where the request succeeded. Fixes: 566f5ca97680 ("mei: Add transport driver for IVSC device") Assisted-by: LLM Signed-off-by: Runyu Xiao Link: https://patch.msgid.link/20260929132245.2152433-1-runyu.xiao@seu.edu.cn Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/vsc-tp.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c index 432bc59f11f9..a5f56121e3be 100644 --- a/drivers/misc/mei/vsc-tp.c +++ b/drivers/misc/mei/vsc-tp.c @@ -496,30 +496,30 @@ static int vsc_tp_probe(struct spi_device *spi) init_waitqueue_head(&tp->xfer_wait); tp->spi = spi; + mutex_init(&tp->mutex); + mutex_init(&tp->event_notify_mutex); + INIT_WORK(&tp->event_work, vsc_tp_event_work); + irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY); ret = request_threaded_irq(spi->irq, NULL, vsc_tp_isr, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), tp); if (ret) - return ret; - - mutex_init(&tp->mutex); - mutex_init(&tp->event_notify_mutex); - INIT_WORK(&tp->event_work, vsc_tp_event_work); + goto err_destroy_lock; /* only one child acpi device */ ret = acpi_dev_for_each_child(ACPI_COMPANION(dev), vsc_tp_match_any, &adev); if (!ret) { ret = -ENODEV; - goto err_destroy_lock; + goto err_free_irq; } pinfo.fwnode = acpi_fwnode_handle(adev); pdev = platform_device_register_full(&pinfo); if (IS_ERR(pdev)) { ret = PTR_ERR(pdev); - goto err_destroy_lock; + goto err_free_irq; } tp->pdev = pdev; @@ -527,9 +527,10 @@ static int vsc_tp_probe(struct spi_device *spi) return 0; -err_destroy_lock: +err_free_irq: free_irq(spi->irq, tp); +err_destroy_lock: cancel_work_sync(&tp->event_work); mutex_destroy(&tp->event_notify_mutex); mutex_destroy(&tp->mutex);