[PATCH] staging: nvec: fix power-off path to not depend on workqueue
Aayush7352 <[email protected]> Tue, 21 Jul 2026 15:26:46 +0530
| Newsgroups | org.kernel.vger.linux-tegra,dev.linux.lists.linux-staging,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Aayush Dixit <[email protected]> nvec_power_off() uses nvec_write_async() which queues work via schedule_work(). During system shutdown or reboot, workqueues may be frozen, so the AP_PWR_DOWN message never reaches the embedded controller and the system hangs instead of powering off. Fix by calling nvec_request_master() directly after queuing the power-off messages, processing the TX queue synchronously in the power-off context. Also add a NULL guard for nvec_power_handle. This addresses the TODO item "add atomic ops in order to fix shutoff/reboot problems" in drivers/staging/nvec/TODO. Signed-off-by: Aayush Dixit <[email protected]> --- This patch has not been tested. Compile-tested and checkpatch-clean only. drivers/staging/nvec/nvec.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 88c416ee0..938ea8f34 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -774,10 +774,23 @@ static void nvec_disable_i2c_slave(struct nvec_chip *nvec) static void nvec_power_off(void) { + struct nvec_chip *nvec = nvec_power_handle; char ap_pwr_down[] = { NVEC_SLEEP, AP_PWR_DOWN }; - nvec_toggle_global_events(nvec_power_handle, false); - nvec_write_async(nvec_power_handle, ap_pwr_down, 2); + if (!nvec) + return; + + nvec_toggle_global_events(nvec, false); + nvec_write_async(nvec, ap_pwr_down, 2); + + /* + * Process the TX queue directly instead of relying on the + * workqueue. Workqueues may be frozen during the power-off + * sequence, so schedule_work() from nvec_write_async() may + * not execute, leaving the AP_PWR_DOWN message unsent and + * the system unable to power off. + */ + nvec_request_master(&nvec->tx_work); } static int tegra_nvec_probe(struct platform_device *pdev) -- 2.55.0