Message ID | 20250415-foo-fix-v2-1-5b45a395e4cc@axis.com |
---|---|
State | New |
Headers | show |
Series | [v4] power: supply: bq27xxx: Retrieve again when busy | expand |
On Tue, 15 Apr 2025 11:40:47 +0800, Jerry Lv wrote: > Multiple applications may access the battery gauge at the same time, so > the gauge may be busy and EBUSY will be returned. The driver will set a > flag to record the EBUSY state, and this flag will be kept until the next > periodic update. When this flag is set, bq27xxx_battery_get_property() > will just return ENODEV until the flag is updated. > > Even if the gauge was busy during the last accessing attempt, returning > ENODEV is not ideal, and can cause confusion in the applications layer. > > [...] Applied, thanks! [1/1] power: supply: bq27xxx: Retrieve again when busy commit: f16d9fb6cf03fdbdefa41a8b32ba1e57afb7ae3d Best regards,
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c index 750fda543308..99631ab46e8e 100644 --- a/drivers/power/supply/bq27xxx_battery.c +++ b/drivers/power/supply/bq27xxx_battery.c @@ -2030,7 +2030,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, mutex_unlock(&di->lock); if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0) - return -ENODEV; + return di->cache.flags; switch (psp) { case POWER_SUPPLY_PROP_STATUS: diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c index ba0d22d90429..868e95f0887e 100644 --- a/drivers/power/supply/bq27xxx_battery_i2c.c +++ b/drivers/power/supply/bq27xxx_battery_i2c.c @@ -6,6 +6,7 @@ * Andrew F. Davis <afd@ti.com> */ +#include <linux/delay.h> #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/module.h> @@ -31,6 +32,7 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg, struct i2c_msg msg[2]; u8 data[2]; int ret; + int retry = 0; if (!client->adapter) return -ENODEV; @@ -47,7 +49,16 @@ static int bq27xxx_battery_i2c_read(struct bq27xxx_device_info *di, u8 reg, else msg[1].len = 2; - ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + do { + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret == -EBUSY && ++retry < 3) { + /* sleep 10 milliseconds when busy */ + usleep_range(10000, 11000); + continue; + } + break; + } while (1); + if (ret < 0) return ret;