summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2023-11-04 16:49:06 +0100
committerSebastian Reichel <sebastian.reichel@collabora.com>2023-11-15 23:13:26 +0100
commitdfcb264a01a9199e8338a548731baf5bbe77ef19 (patch)
tree0bb9aba3e87e1992d09807d18fed4e25e04884b1 /drivers/power
parent5739da3e16ad0ebe99c31cabe960856b53eaaabe (diff)
downloadlwn-dfcb264a01a9199e8338a548731baf5bbe77ef19.tar.gz
lwn-dfcb264a01a9199e8338a548731baf5bbe77ef19.zip
power: supply: bq27xxx: Stop and start delayed work in suspend and resume
This driver uses delayed work to perform periodic battery state read out. This delayed work is not stopped across suspend and resume cycle. The read out can occur early in the resume cycle. In case of an I2C variant of this hardware, that read out triggers I2C transfer. That I2C transfer may happen while the I2C controller is still suspended, which produces a WARNING in the kernel log. Fix this by introducing trivial PM ops, which stop the delayed work before the system enters suspend, and schedule the delayed work right after the system resumes. Signed-off-by: Marek Vasut <marex@denx.de> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20231104154920.68585-1-marex@denx.de Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/supply/bq27xxx_battery.c22
-rw-r--r--drivers/power/supply/bq27xxx_battery_i2c.c1
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 4296600e8912..1c4a9d137744 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -2162,6 +2162,28 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
}
EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);
+#ifdef CONFIG_PM_SLEEP
+static int bq27xxx_battery_suspend(struct device *dev)
+{
+ struct bq27xxx_device_info *di = dev_get_drvdata(dev);
+
+ cancel_delayed_work(&di->work);
+ return 0;
+}
+
+static int bq27xxx_battery_resume(struct device *dev)
+{
+ struct bq27xxx_device_info *di = dev_get_drvdata(dev);
+
+ schedule_delayed_work(&di->work, 0);
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+SIMPLE_DEV_PM_OPS(bq27xxx_battery_battery_pm_ops,
+ bq27xxx_battery_suspend, bq27xxx_battery_resume);
+EXPORT_SYMBOL_GPL(bq27xxx_battery_battery_pm_ops);
+
MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c
index 9b5475590518..3a1798b0c1a7 100644
--- a/drivers/power/supply/bq27xxx_battery_i2c.c
+++ b/drivers/power/supply/bq27xxx_battery_i2c.c
@@ -295,6 +295,7 @@ static struct i2c_driver bq27xxx_battery_i2c_driver = {
.driver = {
.name = "bq27xxx-battery",
.of_match_table = of_match_ptr(bq27xxx_battery_i2c_of_match_table),
+ .pm = &bq27xxx_battery_battery_pm_ops,
},
.probe = bq27xxx_battery_i2c_probe,
.remove = bq27xxx_battery_i2c_remove,