Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

power: supply: axp288_fuel_gauge: Only read PWR_OP_MODE, FG_LOW_CAP_REG regs once

Accessing registers on the AXP288 is quite expensive, so we should avoid
doing unnecessary accesses.

The FG_LOW_CAP_REG never changes underneath us, so we only need to read
it once. Devices with an AXP288 do not have user-replace (let alone
hot-swappable) batteries and the only bit we care about in the
PWR_OP_MODE register is the CHRG_STAT_BAT_PRESENT bit, so we can get
away with only reading the PWR_OP_MODE register once too.

Note that the FG_LOW_CAP_REG is not marked volatile in the regmap, so we
were effectively already reading it once. This change makes this explicit,
this is done as preparation of a further patch which moves all remaining
register accesses in fuel_gauge_get_property() out of that function.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>

authored by

Hans de Goede and committed by
Sebastian Reichel
c371d449 7eef3e66

+21 -16
+21 -16
drivers/power/supply/axp288_fuel_gauge.c
··· 111 111 struct mutex lock; 112 112 int status; 113 113 int max_volt; 114 + int pwr_op; 115 + int low_cap; 114 116 struct dentry *debug_file; 115 117 }; 116 118 ··· 338 336 val->intval = PROP_CURR(value); 339 337 break; 340 338 case POWER_SUPPLY_PROP_PRESENT: 341 - ret = fuel_gauge_reg_readb(info, AXP20X_PWR_OP_MODE); 342 - if (ret < 0) 343 - goto fuel_gauge_read_err; 344 - 345 - if (ret & CHRG_STAT_BAT_PRESENT) 339 + if (info->pwr_op & CHRG_STAT_BAT_PRESENT) 346 340 val->intval = 1; 347 341 else 348 342 val->intval = 0; ··· 353 355 val->intval = (ret & FG_REP_CAP_VAL_MASK); 354 356 break; 355 357 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN: 356 - ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); 357 - if (ret < 0) 358 - goto fuel_gauge_read_err; 359 - val->intval = (ret & 0x0f); 358 + val->intval = (info->low_cap & 0x0f); 360 359 break; 361 360 case POWER_SUPPLY_PROP_TECHNOLOGY: 362 361 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; ··· 393 398 const union power_supply_propval *val) 394 399 { 395 400 struct axp288_fg_info *info = power_supply_get_drvdata(ps); 396 - int ret = 0; 401 + int new_low_cap, ret = 0; 397 402 398 403 mutex_lock(&info->lock); 399 404 switch (prop) { ··· 402 407 ret = -EINVAL; 403 408 break; 404 409 } 405 - ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); 406 - if (ret < 0) 407 - break; 408 - ret &= 0xf0; 409 - ret |= (val->intval & 0xf); 410 - ret = fuel_gauge_reg_writeb(info, AXP288_FG_LOW_CAP_REG, ret); 410 + new_low_cap = info->low_cap; 411 + new_low_cap &= 0xf0; 412 + new_low_cap |= (val->intval & 0xf); 413 + ret = fuel_gauge_reg_writeb(info, AXP288_FG_LOW_CAP_REG, new_low_cap); 414 + if (ret == 0) 415 + info->low_cap = new_low_cap; 411 416 break; 412 417 default: 413 418 ret = -EINVAL; ··· 689 694 info->max_volt = 4350; 690 695 break; 691 696 } 697 + 698 + ret = fuel_gauge_reg_readb(info, AXP20X_PWR_OP_MODE); 699 + if (ret < 0) 700 + goto out_free_iio_chan; 701 + info->pwr_op = ret; 702 + 703 + ret = fuel_gauge_reg_readb(info, AXP288_FG_LOW_CAP_REG); 704 + if (ret < 0) 705 + goto out_free_iio_chan; 706 + info->low_cap = ret; 692 707 693 708 psy_cfg.drv_data = info; 694 709 info->bat = power_supply_register(&pdev->dev, &fuel_gauge_desc, &psy_cfg);