[PATCH 2/2] staging: nvec_power: stop EC queries during system suspend

From: Gustavo Arantes

Date: Thu Mar 12 2026 - 17:15:12 EST


The nvec_power driver continues to schedule its polling and battery
metadata work across system sleep, even though the parent nvec core
suspends the controller.

Track when each nvec_power instance is suspended, stop scheduling new
work once suspend begins, cancel the pending work items, and restart
them on resume. This keeps the driver's EC traffic quiesced while
the parent controller is asleep.

Signed-off-by: Gustavo Arantes <dev.gustavoa@xxxxxxxxx>
---
drivers/staging/nvec/nvec_power.c | 52 +++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c
index 6b3235f41d07..54e5c5cdaf63 100644
--- a/drivers/staging/nvec/nvec_power.c
+++ b/drivers/staging/nvec/nvec_power.c
@@ -25,6 +25,7 @@ struct nvec_power {
struct delayed_work poller;
struct work_struct bat_init;
struct nvec_chip *nvec;
+ bool suspended;
int on;
int bat_present;
int bat_status;
@@ -158,7 +159,8 @@ static int nvec_power_bat_notifier(struct notifier_block *nb,
if (res->plc[0] & 1) {
if (power->bat_present == 0) {
status_changed = 1;
- schedule_work(&power->bat_init);
+ if (!READ_ONCE(power->suspended))
+ schedule_work(&power->bat_init);
}

power->bat_present = 1;
@@ -398,7 +400,9 @@ static void nvec_power_poll(struct work_struct *work)
dev_warn(power->nvec->dev,
"failed to query battery status: %d\n", ret);

- schedule_delayed_work(to_delayed_work(work), msecs_to_jiffies(5000));
+ if (!READ_ONCE(power->suspended))
+ schedule_delayed_work(to_delayed_work(work),
+ msecs_to_jiffies(5000));
};

static int nvec_power_probe(struct platform_device *pdev)
@@ -471,11 +475,55 @@ static void nvec_power_remove(struct platform_device *pdev)
}
}

+#ifdef CONFIG_PM_SLEEP
+static int nvec_power_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct nvec_power *power = dev_get_drvdata(dev);
+
+ WRITE_ONCE(power->suspended, true);
+
+ switch (pdev->id) {
+ case AC:
+ cancel_delayed_work_sync(&power->poller);
+ break;
+ case BAT:
+ cancel_work_sync(&power->bat_init);
+ break;
+ }
+
+ return 0;
+}
+
+static int nvec_power_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct nvec_power *power = dev_get_drvdata(dev);
+
+ WRITE_ONCE(power->suspended, false);
+
+ switch (pdev->id) {
+ case AC:
+ schedule_delayed_work(&power->poller, msecs_to_jiffies(5000));
+ break;
+ case BAT:
+ schedule_work(&power->bat_init);
+ break;
+ }
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(nvec_power_pm_ops, nvec_power_suspend,
+ nvec_power_resume);
+
static struct platform_driver nvec_power_driver = {
.probe = nvec_power_probe,
.remove = nvec_power_remove,
.driver = {
.name = "nvec-power",
+ .pm = &nvec_power_pm_ops,
}
};

--
2.53.0