Skip to content

Commit

Permalink
power: supply: bq27xxx: Stop and start delayed work in suspend and re…
Browse files Browse the repository at this point in the history
…sume

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>
  • Loading branch information
Marek Vasut authored and Sebastian Reichel committed Nov 15, 2023
1 parent 5739da3 commit dfcb264
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/power/supply/bq27xxx_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
1 change: 1 addition & 0 deletions drivers/power/supply/bq27xxx_battery_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions include/linux/power/bq27xxx_battery.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ struct bq27xxx_device_info {
void bq27xxx_battery_update(struct bq27xxx_device_info *di);
int bq27xxx_battery_setup(struct bq27xxx_device_info *di);
void bq27xxx_battery_teardown(struct bq27xxx_device_info *di);
extern const struct dev_pm_ops bq27xxx_battery_battery_pm_ops;

#endif

0 comments on commit dfcb264

Please sign in to comment.