@@ -1527,6 +1527,31 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
return POWER_SUPPLY_HEALTH_GOOD;
}
+static int bq27xxx_battery_read_status(struct bq27xxx_device_info *di)
+{
+ int status;
+
+ if (di->opts & BQ27XXX_O_ZERO) {
+ if (di->cache.flags & BQ27000_FLAG_FC)
+ status = POWER_SUPPLY_STATUS_FULL;
+ else if (di->cache.flags & BQ27000_FLAG_CHGS)
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ else if (power_supply_am_i_supplied(di->bat) > 0)
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ else
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
+ } else {
+ if (di->cache.flags & BQ27XXX_FLAG_FC)
+ status = POWER_SUPPLY_STATUS_FULL;
+ else if (di->cache.flags & BQ27XXX_FLAG_DSC)
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
+ else
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ }
+
+ return status;
+}
+
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
{
struct bq27xxx_reg_cache cache = {0, };
@@ -1547,6 +1572,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
cache.time_to_full = -ENODATA;
cache.charge_full = -ENODATA;
cache.health = -ENODATA;
+ cache.status = bq27xxx_battery_read_status(di);
} else {
if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
@@ -1559,6 +1585,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
cache.energy = bq27xxx_battery_read_energy(di);
cache.health = bq27xxx_battery_read_health(di);
+ cache.status = bq27xxx_battery_read_status(di);
}
if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
cache.cycle_count = bq27xxx_battery_read_cyct(di);
@@ -1570,7 +1597,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
di->charge_design_full = bq27xxx_battery_read_dcap(di);
}
- if (di->cache.capacity != cache.capacity)
+ if ((di->cache.capacity != cache.capacity) || (di->cache.status != cache.status))
power_supply_changed(di->bat);
if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
@@ -1625,34 +1652,6 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
return 0;
}
-static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
- union power_supply_propval *val)
-{
- int status;
-
- if (di->opts & BQ27XXX_O_ZERO) {
- if (di->cache.flags & BQ27000_FLAG_FC)
- status = POWER_SUPPLY_STATUS_FULL;
- else if (di->cache.flags & BQ27000_FLAG_CHGS)
- status = POWER_SUPPLY_STATUS_CHARGING;
- else if (power_supply_am_i_supplied(di->bat) > 0)
- status = POWER_SUPPLY_STATUS_NOT_CHARGING;
- else
- status = POWER_SUPPLY_STATUS_DISCHARGING;
- } else {
- if (di->cache.flags & BQ27XXX_FLAG_FC)
- status = POWER_SUPPLY_STATUS_FULL;
- else if (di->cache.flags & BQ27XXX_FLAG_DSC)
- status = POWER_SUPPLY_STATUS_DISCHARGING;
- else
- status = POWER_SUPPLY_STATUS_CHARGING;
- }
-
- val->intval = status;
-
- return 0;
-}
-
static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
union power_supply_propval *val)
{
@@ -1733,7 +1732,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
- ret = bq27xxx_battery_status(di, val);
+ ret = bq27xxx_simple_value(di->cache.status, val);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
ret = bq27xxx_battery_voltage(di, val);
@@ -49,6 +49,7 @@ struct bq27xxx_reg_cache {
int flags;
int power_avg;
int health;
+ int status;
};
struct bq27xxx_device_info {
It seems that bq27xxx_battery_update does not call power_supply_changed when the charging status changes, and instead only when the capacity changes. This can cause considerable delays in reporting charging status changes to userspace. This patch turns the battery status reading function into one that returns the value directly (as other *_read functions), adds the status to the cache, uses the cache when reporting the values and finally will trigger power_supply_changed when the charging status changes. Signed-off-by: Merlijn Wajer <merlijn@wizzup.org> --- drivers/power/supply/bq27xxx_battery.c | 59 +++++++++++++++++----------------- include/linux/power/bq27xxx_battery.h | 1 + 2 files changed, 30 insertions(+), 30 deletions(-)