Skip to content

Commit

Permalink
power: supply_core: Pass pointer to battery info
Browse files Browse the repository at this point in the history
The function to retrieve battery info (from the device tree) assumes
we have a static info struct that gets populated by calling into
power_supply_get_battery_info().

This is awkward since I want to support tables of static battery
info by just assigning a pointer to all info based on e.g. a
compatible value in the device tree.

We also have a mixture of static and dynamically allocated
variables here.

Bite the bullet and let power_supply_get_battery_info() allocate
also the memory used for the very top level
struct power_supply_battery_info container. Pass pointers
around and lifecycle this with the psy device just like the
stuff we allocate inside it.

Change all current users over.

As part of the change, initializers need to be added to some
previously uninitialized fields in struct
power_supply_battery_info.

Reviewed-By: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
  • Loading branch information
Linus Walleij authored and Sebastian Reichel committed Jan 3, 2022
1 parent be2c0d5 commit 25fd330
Show file tree
Hide file tree
Showing 19 changed files with 157 additions and 127 deletions.
2 changes: 1 addition & 1 deletion drivers/power/supply/ab8500-bm.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ struct ab8500_bm_charger_parameters {
* @fg_params fuel gauge parameters
*/
struct ab8500_bm_data {
struct power_supply_battery_info bi;
struct power_supply_battery_info *bi;
int temp_now;
int temp_interval_chg;
int temp_interval_nochg;
Expand Down
7 changes: 4 additions & 3 deletions drivers/power/supply/ab8500_bmdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,16 @@ struct ab8500_bm_data ab8500_bm_data = {
int ab8500_bm_of_probe(struct power_supply *psy,
struct ab8500_bm_data *bm)
{
struct power_supply_battery_info *bi = &bm->bi;
struct power_supply_battery_info *bi;
struct device *dev = &psy->dev;
int ret;

ret = power_supply_get_battery_info(psy, bi);
ret = power_supply_get_battery_info(psy, &bm->bi);
if (ret) {
dev_err(dev, "cannot retrieve battery info\n");
return ret;
}
bi = bm->bi;

/* Fill in defaults for any data missing from the device tree */
if (bi->charge_full_design_uah < 0)
Expand Down Expand Up @@ -240,5 +241,5 @@ int ab8500_bm_of_probe(struct power_supply *psy,
void ab8500_bm_of_remove(struct power_supply *psy,
struct ab8500_bm_data *bm)
{
power_supply_put_battery_info(psy, &bm->bi);
power_supply_put_battery_info(psy, bm->bi);
}
10 changes: 7 additions & 3 deletions drivers/power/supply/ab8500_btemp.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,12 +451,13 @@ static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di,
*/
static int ab8500_btemp_measure_temp(struct ab8500_btemp *di)
{
struct power_supply_battery_info *bi = di->bm->bi;
int temp, ret;
static int prev;
int rbat, rntc, vntc;

if ((di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL) &&
(di->bm->bi.technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) {
(bi && (bi->technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN))) {

rbat = ab8500_btemp_get_batctrl_res(di);
if (rbat < 0) {
Expand Down Expand Up @@ -540,7 +541,7 @@ static int ab8500_btemp_id(struct ab8500_btemp *di)
* that need it.
*/
if ((di->bm->adc_therm == AB8500_ADC_THERM_BATCTRL) &&
(di->bm->bi.technology == POWER_SUPPLY_TECHNOLOGY_LIPO) &&
(di->bm->bi && (di->bm->bi->technology == POWER_SUPPLY_TECHNOLOGY_LIPO)) &&
(res <= 53407) && (res >= 12500)) {
dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n");
di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA;
Expand Down Expand Up @@ -807,7 +808,10 @@ static int ab8500_btemp_get_property(struct power_supply *psy,
val->intval = 1;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = di->bm->bi.technology;
if (di->bm->bi)
val->intval = di->bm->bi->technology;
else
val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = ab8500_btemp_get_temp(di);
Expand Down
16 changes: 8 additions & 8 deletions drivers/power/supply/ab8500_chargalg.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ static void ab8500_chargalg_state_to(struct ab8500_chargalg *di,

static int ab8500_chargalg_check_charger_enable(struct ab8500_chargalg *di)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;

switch (di->charge_state) {
case STATE_NORMAL:
Expand Down Expand Up @@ -731,7 +731,7 @@ static void ab8500_chargalg_start_charging(struct ab8500_chargalg *di,
*/
static void ab8500_chargalg_check_temp(struct ab8500_chargalg *di)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;

if (di->batt_data.temp > (bi->temp_alert_min + di->t_hyst_norm) &&
di->batt_data.temp < (bi->temp_alert_max - di->t_hyst_norm)) {
Expand Down Expand Up @@ -802,10 +802,10 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di)
if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
di->charge_state == STATE_NORMAL &&
!di->maintenance_chg && (di->batt_data.volt_uv >=
di->bm->bi.overvoltage_limit_uv ||
di->bm->bi->overvoltage_limit_uv ||
di->events.usb_cv_active || di->events.ac_cv_active) &&
di->batt_data.avg_curr_ua <
di->bm->bi.charge_term_current_ua &&
di->bm->bi->charge_term_current_ua &&
di->batt_data.avg_curr_ua > 0) {
if (++di->eoc_cnt >= EOC_COND_CNT) {
di->eoc_cnt = 0;
Expand All @@ -827,7 +827,7 @@ static void ab8500_chargalg_end_of_charge(struct ab8500_chargalg *di)

static void init_maxim_chg_curr(struct ab8500_chargalg *di)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;

di->ccm.original_iset_ua = bi->constant_charge_current_max_ua;
di->ccm.current_iset_ua = bi->constant_charge_current_max_ua;
Expand Down Expand Up @@ -920,7 +920,7 @@ static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di)

static void handle_maxim_chg_curr(struct ab8500_chargalg *di)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;
enum maxim_ret ret;
int result;

Expand Down Expand Up @@ -1299,7 +1299,7 @@ static void ab8500_chargalg_external_power_changed(struct power_supply *psy)
*/
static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;
int charger_status;
int ret;
int curr_step_lvl_ua;
Expand Down Expand Up @@ -1723,7 +1723,7 @@ static int ab8500_chargalg_get_property(struct power_supply *psy,
if (di->events.batt_ovv) {
val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
} else if (di->events.btemp_underover) {
if (di->batt_data.temp <= di->bm->bi.temp_min)
if (di->batt_data.temp <= di->bm->bi->temp_min)
val->intval = POWER_SUPPLY_HEALTH_COLD;
else
val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
Expand Down
18 changes: 10 additions & 8 deletions drivers/power/supply/ab8500_fg.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ static int ab8500_fg_bat_voltage(struct ab8500_fg *di)
*/
static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage_uv)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;

/* Multiply by 10 because the capacity is tracked in per mille */
return power_supply_batinfo_ocv2cap(bi, voltage_uv, di->bat_temp) * 10;
Expand Down Expand Up @@ -881,7 +881,7 @@ static int ab8500_fg_uncomp_volt_to_capacity(struct ab8500_fg *di)
*/
static int ab8500_fg_battery_resistance(struct ab8500_fg *di)
{
struct power_supply_battery_info *bi = &di->bm->bi;
struct power_supply_battery_info *bi = di->bm->bi;
int resistance_percent = 0;
int resistance;

Expand Down Expand Up @@ -2140,11 +2140,13 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
struct power_supply *ext = dev_get_drvdata(dev);
const char **supplicants = (const char **)ext->supplied_to;
struct ab8500_fg *di;
struct power_supply_battery_info *bi;
union power_supply_propval ret;
int j;

psy = (struct power_supply *)data;
di = power_supply_get_drvdata(psy);
bi = di->bm->bi;

/*
* For all psy where the name of your driver
Expand Down Expand Up @@ -2207,22 +2209,22 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
switch (ext->desc->type) {
case POWER_SUPPLY_TYPE_BATTERY:
if (!di->flags.batt_id_received &&
(di->bm->bi.technology !=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN)) {
(bi && (bi->technology !=
POWER_SUPPLY_TECHNOLOGY_UNKNOWN))) {
const struct ab8500_battery_type *b;

b = di->bm->bat_type;

di->flags.batt_id_received = true;

di->bat_cap.max_mah_design =
di->bm->bi.charge_full_design_uah;
di->bm->bi->charge_full_design_uah;

di->bat_cap.max_mah =
di->bat_cap.max_mah_design;

di->vbat_nom_uv =
di->bm->bi.voltage_max_design_uv;
di->bm->bi->voltage_max_design_uv;
}

if (ret.intval)
Expand Down Expand Up @@ -2992,9 +2994,9 @@ static int ab8500_fg_bind(struct device *dev, struct device *master,
return -ENOMEM;
}

di->bat_cap.max_mah_design = di->bm->bi.charge_full_design_uah;
di->bat_cap.max_mah_design = di->bm->bi->charge_full_design_uah;
di->bat_cap.max_mah = di->bat_cap.max_mah_design;
di->vbat_nom_uv = di->bm->bi.voltage_max_design_uv;
di->vbat_nom_uv = di->bm->bi->voltage_max_design_uv;

/* Start the coulomb counter */
ab8500_fg_coulomb_counter(di, true);
Expand Down
6 changes: 3 additions & 3 deletions drivers/power/supply/axp20x_battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ static int axp20x_power_probe(struct platform_device *pdev)
{
struct axp20x_batt_ps *axp20x_batt;
struct power_supply_config psy_cfg = {};
struct power_supply_battery_info info;
struct power_supply_battery_info *info;
struct device *dev = &pdev->dev;

if (!of_device_is_available(pdev->dev.of_node))
Expand Down Expand Up @@ -615,8 +615,8 @@ static int axp20x_power_probe(struct platform_device *pdev)
}

if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) {
int vmin = info.voltage_min_design_uv;
int ccc = info.constant_charge_current_max_ua;
int vmin = info->voltage_min_design_uv;
int ccc = info->constant_charge_current_max_ua;

if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt,
vmin))
Expand Down
24 changes: 13 additions & 11 deletions drivers/power/supply/bd99954-charger.c
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ struct dt_init {
static int bd9995x_fw_probe(struct bd9995x_device *bd)
{
int ret;
struct power_supply_battery_info info;
struct power_supply_battery_info *info;
u32 property;
int i;
int regval;
Expand All @@ -891,49 +891,41 @@ static int bd9995x_fw_probe(struct bd9995x_device *bd)
struct battery_init battery_inits[] = {
{
.name = "trickle-charging current",
.info_data = &info.tricklecharge_current_ua,
.range = &charging_current_ranges[0],
.ranges = 2,
.data = &init->itrich_set,
}, {
.name = "pre-charging current",
.info_data = &info.precharge_current_ua,
.range = &charging_current_ranges[0],
.ranges = 2,
.data = &init->iprech_set,
}, {
.name = "pre-to-trickle charge voltage threshold",
.info_data = &info.precharge_voltage_max_uv,
.range = &trickle_to_pre_threshold_ranges[0],
.ranges = 2,
.data = &init->vprechg_th_set,
}, {
.name = "charging termination current",
.info_data = &info.charge_term_current_ua,
.range = &charging_current_ranges[0],
.ranges = 2,
.data = &init->iterm_set,
}, {
.name = "charging re-start voltage",
.info_data = &info.charge_restart_voltage_uv,
.range = &charge_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vrechg_set,
}, {
.name = "battery overvoltage limit",
.info_data = &info.overvoltage_limit_uv,
.range = &charge_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vbatovp_set,
}, {
.name = "fast-charging max current",
.info_data = &info.constant_charge_current_max_ua,
.range = &fast_charge_current_ranges[0],
.ranges = 1,
.data = &init->ichg_set,
}, {
.name = "fast-charging voltage",
.info_data = &info.constant_charge_voltage_max_uv,
.range = &charge_voltage_regulation_ranges[0],
.ranges = 2,
.data = &init->vfastchg_reg_set1,
Expand Down Expand Up @@ -966,6 +958,16 @@ static int bd9995x_fw_probe(struct bd9995x_device *bd)
if (ret < 0)
return ret;

/* Put pointers to the generic battery info */
battery_inits[0].info_data = &info->tricklecharge_current_ua;
battery_inits[1].info_data = &info->precharge_current_ua;
battery_inits[2].info_data = &info->precharge_voltage_max_uv;
battery_inits[3].info_data = &info->charge_term_current_ua;
battery_inits[4].info_data = &info->charge_restart_voltage_uv;
battery_inits[5].info_data = &info->overvoltage_limit_uv;
battery_inits[6].info_data = &info->constant_charge_current_max_ua;
battery_inits[7].info_data = &info->constant_charge_voltage_max_uv;

for (i = 0; i < ARRAY_SIZE(battery_inits); i++) {
int val = *battery_inits[i].info_data;
const struct linear_range *range = battery_inits[i].range;
Expand All @@ -980,7 +982,7 @@ static int bd9995x_fw_probe(struct bd9995x_device *bd)
dev_err(bd->dev, "Unsupported value for %s\n",
battery_inits[i].name);

power_supply_put_battery_info(bd->charger, &info);
power_supply_put_battery_info(bd->charger, info);
return -EINVAL;
}
if (!found) {
Expand All @@ -991,7 +993,7 @@ static int bd9995x_fw_probe(struct bd9995x_device *bd)
*(battery_inits[i].data) = regval;
}

power_supply_put_battery_info(bd->charger, &info);
power_supply_put_battery_info(bd->charger, info);

for (i = 0; i < ARRAY_SIZE(props); i++) {
ret = device_property_read_u32(bd->dev, props[i].prop,
Expand Down
6 changes: 3 additions & 3 deletions drivers/power/supply/bq24190_charger.c
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,7 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
static int bq24190_get_config(struct bq24190_dev_info *bdi)
{
const char * const s = "ti,system-minimum-microvolt";
struct power_supply_battery_info info = {};
struct power_supply_battery_info *info;
int v;

if (device_property_read_u32(bdi->dev, s, &v) == 0) {
Expand All @@ -1684,15 +1684,15 @@ static int bq24190_get_config(struct bq24190_dev_info *bdi)

if (bdi->dev->of_node &&
!power_supply_get_battery_info(bdi->charger, &info)) {
v = info.precharge_current_ua / 1000;
v = info->precharge_current_ua / 1000;
if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
&& v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
bdi->iprechg = v;
else
dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
v);

v = info.charge_term_current_ua / 1000;
v = info->charge_term_current_ua / 1000;
if (v >= BQ24190_REG_PCTCC_ITERM_MIN
&& v <= BQ24190_REG_PCTCC_ITERM_MAX)
bdi->iterm = v;
Expand Down
8 changes: 4 additions & 4 deletions drivers/power/supply/bq2515x_charger.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ static int bq2515x_power_supply_register(struct bq2515x_device *bq2515x,
static int bq2515x_hw_init(struct bq2515x_device *bq2515x)
{
int ret;
struct power_supply_battery_info bat_info = { };
struct power_supply_battery_info *bat_info;

ret = bq2515x_disable_watchdog_timers(bq2515x);
if (ret)
Expand All @@ -969,13 +969,13 @@ static int bq2515x_hw_init(struct bq2515x_device *bq2515x)

} else {
bq2515x->init_data.ichg =
bat_info.constant_charge_current_max_ua;
bat_info->constant_charge_current_max_ua;

bq2515x->init_data.vbatreg =
bat_info.constant_charge_voltage_max_uv;
bat_info->constant_charge_voltage_max_uv;

bq2515x->init_data.iprechg =
bat_info.precharge_current_ua;
bat_info->precharge_current_ua;
}

ret = bq2515x_set_const_charge_current(bq2515x,
Expand Down
Loading

0 comments on commit 25fd330

Please sign in to comment.