Re: [PATCH] power: supply: bq27xxx: Introduce parameter to config cache regs

From: Sebastian Reichel
Date: Wed Feb 21 2024 - 18:03:18 EST


Hi,

On Mon, Feb 19, 2024 at 06:05:40PM +0800, Hermes Zhang wrote:
> Since all of the regs in the bq27xxx_reg_cache are now cached, a simple
> property read (such as temperature) will need nine I2C transmissions.
> Introduce a new module parameter to enable the reg cache to be configured,
> which decrease the amount of unnecessary I2C transmission and preventing
> the error -16 (EBUSY) happen when working on an I2C bus that is shared by
> many devices.

So the problem is not the caching, but the grouping. So instead
of adding this hack, please change the code to do the caching
per register. That way you can just keep the caching enabled and
don't need any custom module parameters.

-- Sebastian

> Signed-off-by: Hermes Zhang <Hermes.Zhang@xxxxxxxx>
> ---
> drivers/power/supply/bq27xxx_battery.c | 65 +++++++++++++++++++-------
> include/linux/power/bq27xxx_battery.h | 9 ++++
> 2 files changed, 58 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
> index 1c4a9d137744..45fd956ec961 100644
> --- a/drivers/power/supply/bq27xxx_battery.c
> +++ b/drivers/power/supply/bq27xxx_battery.c
> @@ -1100,6 +1100,11 @@ module_param_cb(poll_interval, &param_ops_poll_interval, &poll_interval, 0644);
> MODULE_PARM_DESC(poll_interval,
> "battery poll interval in seconds - 0 disables polling");
>
> +static unsigned int bq27xxx_cache_mask = 0xFF;
> +module_param(bq27xxx_cache_mask, uint, 0644);
> +MODULE_PARM_DESC(bq27xxx_cache_mask,
> + "mask for bq27xxx reg cache - 0 disables reg cache");
> +
> /*
> * Common code for BQ27xxx devices
> */
> @@ -1842,21 +1847,29 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
> if ((cache.flags & 0xff) == 0xff)
> cache.flags = -1; /* read error */
> if (cache.flags >= 0) {
> - cache.temperature = bq27xxx_battery_read_temperature(di);
> - if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
> + if (bq27xxx_cache_mask & BQ27XXX_CACHE_TEMP)
> + cache.temperature = bq27xxx_battery_read_temperature(di);
> + if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR &&
> + bq27xxx_cache_mask & BQ27XXX_CACHE_TTE)
> cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
> - if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
> + if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR &&
> + bq27xxx_cache_mask & BQ27XXX_CACHE_TTECP)
> cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
> - if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
> + if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR &&
> + bq27xxx_cache_mask & BQ27XXX_CACHE_TTF)
> cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
>
> - cache.charge_full = bq27xxx_battery_read_fcc(di);
> - cache.capacity = bq27xxx_battery_read_soc(di);
> - if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
> + if (bq27xxx_cache_mask & BQ27XXX_CACHE_CHARGE_FULL)
> + cache.charge_full = bq27xxx_battery_read_fcc(di);
> + if (bq27xxx_cache_mask & BQ27XXX_CACHE_CAPACITY)
> + cache.capacity = bq27xxx_battery_read_soc(di);
> + if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR &&
> + bq27xxx_cache_mask & BQ27XXX_CACHE_ENERGY)
> cache.energy = bq27xxx_battery_read_energy(di);
> di->cache.flags = cache.flags;
> cache.health = bq27xxx_battery_read_health(di);
> - if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
> + if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR &&
> + bq27xxx_cache_mask & BQ27XXX_CACHE_CYCT)
> cache.cycle_count = bq27xxx_battery_read_cyct(di);
>
> /*
> @@ -2004,6 +2017,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
> {
> int ret = 0;
> struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
> + int tmp;
>
> mutex_lock(&di->lock);
> if (time_is_before_jiffies(di->last_update + 5 * HZ))
> @@ -2027,24 +2041,37 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
> ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
> break;
> case POWER_SUPPLY_PROP_CAPACITY:
> - ret = bq27xxx_simple_value(di->cache.capacity, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_CAPACITY ?
> + di->cache.capacity : bq27xxx_battery_read_soc(di);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
> ret = bq27xxx_battery_capacity_level(di, val);
> break;
> case POWER_SUPPLY_PROP_TEMP:
> - ret = bq27xxx_simple_value(di->cache.temperature, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_TEMP ?
> + di->cache.temperature : bq27xxx_battery_read_temperature(di);
> + ret = bq27xxx_simple_value(tmp, val);
> if (ret == 0)
> val->intval -= 2731; /* convert decidegree k to c */
> break;
> case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
> - ret = bq27xxx_simple_value(di->cache.time_to_empty, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_TTE ?
> + di->cache.time_to_empty :
> + bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
> - ret = bq27xxx_simple_value(di->cache.time_to_empty_avg, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_TTECP ?
> + di->cache.time_to_empty_avg :
> + bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
> - ret = bq27xxx_simple_value(di->cache.time_to_full, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_TTF ?
> + di->cache.time_to_full :
> + bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_TECHNOLOGY:
> if (di->opts & BQ27XXX_O_MUL_CHEM)
> @@ -2059,7 +2086,9 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
> ret = bq27xxx_simple_value(bq27xxx_battery_read_rc(di), val);
> break;
> case POWER_SUPPLY_PROP_CHARGE_FULL:
> - ret = bq27xxx_simple_value(di->cache.charge_full, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_CHARGE_FULL ?
> + di->cache.charge_full : bq27xxx_battery_read_fcc(di);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
> ret = bq27xxx_simple_value(di->charge_design_full, val);
> @@ -2072,10 +2101,14 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
> case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> return -EINVAL;
> case POWER_SUPPLY_PROP_CYCLE_COUNT:
> - ret = bq27xxx_simple_value(di->cache.cycle_count, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_CYCT ?
> + di->cache.cycle_count : bq27xxx_battery_read_cyct(di);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_ENERGY_NOW:
> - ret = bq27xxx_simple_value(di->cache.energy, val);
> + tmp = bq27xxx_cache_mask & BQ27XXX_CACHE_ENERGY ?
> + di->cache.energy : bq27xxx_battery_read_energy(di);
> + ret = bq27xxx_simple_value(tmp, val);
> break;
> case POWER_SUPPLY_PROP_POWER_AVG:
> ret = bq27xxx_battery_pwr_avg(di, val);
> diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
> index 7d8025fb74b7..29d1e7107ee2 100644
> --- a/include/linux/power/bq27xxx_battery.h
> +++ b/include/linux/power/bq27xxx_battery.h
> @@ -4,6 +4,15 @@
>
> #include <linux/power_supply.h>
>
> +#define BQ27XXX_CACHE_TEMP (1 << 0)
> +#define BQ27XXX_CACHE_TTE (1 << 1)
> +#define BQ27XXX_CACHE_TTECP (1 << 2)
> +#define BQ27XXX_CACHE_TTF (1 << 3)
> +#define BQ27XXX_CACHE_CHARGE_FULL (1 << 4)
> +#define BQ27XXX_CACHE_CYCT (1 << 5)
> +#define BQ27XXX_CACHE_CAPACITY (1 << 6)
> +#define BQ27XXX_CACHE_ENERGY (1 << 7)
> +
> enum bq27xxx_chip {
> BQ27000 = 1, /* bq27000, bq27200 */
> BQ27010, /* bq27010, bq27210 */
> --
> 2.39.2
>

Attachment: signature.asc
Description: PGP signature