Re: [PATCH] staging: nvec: fix power-off path to not depend on workqueue
Marc Dietrich <[email protected]> Tue, 28 Jul 2026 10:49:09 +0200 (CEST)
| Newsgroups | org.kernel.vger.linux-tegra,dev.linux.lists.linux-staging,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hello Aayush, On Tue, 21 Jul 2026, Aayush7352 wrote: > 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. right, but not only for PWR_DOWN but also for disabling events. Best would= =20 be to move the toggle events to the shutdown preparation phase. > 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 still won't work and cannot be tested as long as the driver does not= =20 support atomic i2c tranfers, which should be implemented first. > This addresses the TODO item "add atomic ops in order to fix > shutoff/reboot problems" in drivers/staging/nvec/TODO. No, atomic ops means to implement irq less i2c transfers (polling). Marc > Signed-off-by: Aayush Dixit <[email protected]> > --- > This patch has not been tested. Compile-tested and checkpatch-clean onl= y. > > 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_chi= p *nvec) > > static void nvec_power_off(void) > { > + struct nvec_chip *nvec =3D nvec_power_handle; > char ap_pwr_down[] =3D { 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) > --=20 > 2.55.0 > >