From 0c804048d94184a86ac055925e79efbe7a2fa50b Mon Sep 17 00:00:00 2001 From: Rakesh Kota Date: Thu, 18 Jan 2024 11:57:12 +0530 Subject: [PATCH] power: supply: bq27xxx: Add Hibernate mode support In Hibernate mode, the HW and SW state may go out of sync, as the HW is turned off, but SW state is preserved. This may cause the irqs to not work properly after the Hibernate exit. To avoid this issue, in the Hibernate exit path, free and re-request the interrupts, to make sure that the HW state is restored. Change-Id: I1b38acd6b76f1629d0ed76066b0b5f2ae500a0ce Signed-off-by: Rakesh Kota Signed-off-by: Monish Chunara --- drivers/power/supply/bq27xxx_battery_i2c.c | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c index 767a188f9736..ec3a8873b037 100644 --- a/drivers/power/supply/bq27xxx_battery_i2c.c +++ b/drivers/power/supply/bq27xxx_battery_i2c.c @@ -167,6 +167,28 @@ static int bq27xx_parse_dt(struct bq27xxx_device_info *di, } #endif +static int bq27xxx_restore(struct device *dev) +{ + int ret = 0; + struct i2c_client *client = to_i2c_client(dev); + struct bq27xxx_device_info *di = i2c_get_clientdata(client); + + if (client->irq > 0) { + disable_irq_nosync(client->irq); + devm_free_irq(dev, client->irq, di); + ret = request_threaded_irq(client->irq, + NULL, bq27xxx_battery_irq_handler_thread, + IRQF_ONESHOT, + di->name, di); + } + + return ret; +} + +static const struct dev_pm_ops bq27xxx_pm_ops = { + .restore = bq27xxx_restore, +}; + static int bq27xxx_battery_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -340,6 +362,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_pm_ops, }, .probe = bq27xxx_battery_i2c_probe, .remove = bq27xxx_battery_i2c_remove,