power: pm8921-charger: Add error handling logic
Handle return errors at multiple locations and report them
appropriately. While at it, fix functions which can report
valid negative values.
CRs-Fixed: 389633
Change-Id: Ib3b8121d721d17bc9086decd94ee10239a2ec5f4
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 03b3e0d..bbe5de7 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1576,13 +1576,18 @@
return (int)result.physical;
}
-static unsigned int voltage_based_capacity(struct pm8921_chg_chip *chip)
+static int voltage_based_capacity(struct pm8921_chg_chip *chip)
{
- unsigned int current_voltage_uv = get_prop_battery_uvolts(chip);
- unsigned int current_voltage_mv = current_voltage_uv / 1000;
+ int current_voltage_uv = get_prop_battery_uvolts(chip);
+ int current_voltage_mv = current_voltage_uv / 1000;
unsigned int low_voltage = chip->min_voltage_mv;
unsigned int high_voltage = chip->max_voltage_mv;
+ if (current_voltage_uv < 0) {
+ pr_err("Error reading current voltage\n");
+ return -EIO;
+ }
+
if (current_voltage_mv <= low_voltage)
return 0;
else if (current_voltage_mv >= high_voltage)
@@ -1640,6 +1645,11 @@
if (percent_soc == -ENXIO)
percent_soc = voltage_based_capacity(chip);
+ if (percent_soc < 0) {
+ pr_err("Unable to read battery voltage\n");
+ goto fail_voltage;
+ }
+
if (percent_soc <= 10)
pr_warn_ratelimited("low battery charge = %d%%\n",
percent_soc);
@@ -1660,30 +1670,34 @@
pm_chg_vbatdet_set(the_chip, PM8921_CHG_VBATDET_MAX);
}
+fail_voltage:
chip->recent_reported_soc = percent_soc;
return percent_soc;
}
-static int get_prop_batt_current_max(struct pm8921_chg_chip *chip)
+static int get_prop_batt_current_max(struct pm8921_chg_chip *chip, int *curr)
{
- return pm8921_bms_get_current_max();
+ *curr = 0;
+ *curr = pm8921_bms_get_current_max();
+ if (*curr == -EINVAL)
+ return -EINVAL;
+
+ return 0;
}
-static int get_prop_batt_current(struct pm8921_chg_chip *chip)
+static int get_prop_batt_current(struct pm8921_chg_chip *chip, int *curr)
{
- int result_ua, rc;
+ int rc;
- rc = pm8921_bms_get_battery_current(&result_ua);
+ *curr = 0;
+ rc = pm8921_bms_get_battery_current(curr);
if (rc == -ENXIO) {
- rc = pm8xxx_ccadc_get_battery_current(&result_ua);
+ rc = pm8xxx_ccadc_get_battery_current(curr);
}
-
- if (rc) {
+ if (rc)
pr_err("unable to get batt current rc = %d\n", rc);
- return rc;
- } else {
- return result_ua;
- }
+
+ return rc;
}
static int get_prop_batt_fcc(struct pm8921_chg_chip *chip)
@@ -1696,17 +1710,15 @@
return rc;
}
-static int get_prop_batt_charge_now(struct pm8921_chg_chip *chip)
+static int get_prop_batt_charge_now(struct pm8921_chg_chip *chip, int *cc_uah)
{
int rc;
- int cc_uah;
- rc = pm8921_bms_cc_uah(&cc_uah);
+ *cc_uah = 0;
+ rc = pm8921_bms_cc_uah(cc_uah);
+ if (rc)
+ pr_err("unable to get batt fcc rc = %d\n", rc);
- if (rc == 0)
- return cc_uah;
-
- pr_err("unable to get batt fcc rc = %d\n", rc);
return rc;
}
@@ -1750,13 +1762,15 @@
}
#define MAX_TOLERABLE_BATT_TEMP_DDC 680
-static int get_prop_batt_temp(struct pm8921_chg_chip *chip)
+static int get_prop_batt_temp(struct pm8921_chg_chip *chip, int *temp)
{
int rc;
struct pm8xxx_adc_chan_result result;
- if (chip->battery_less_hardware)
- return 300;
+ if (chip->battery_less_hardware) {
+ *temp = 300;
+ return 0;
+ }
rc = pm8xxx_adc_read(chip->batt_temp_channel, &result);
if (rc) {
@@ -1770,16 +1784,19 @@
pr_err("BATT_TEMP= %d > 68degC, device will be shutdown\n",
(int) result.physical);
- return (int)result.physical;
+ *temp = (int)result.physical;
+
+ return rc;
}
static int pm_batt_power_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
+ int rc = 0;
+ int value;
struct pm8921_chg_chip *chip = container_of(psy, struct pm8921_chg_chip,
batt_psy);
-
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = get_prop_batt_status(chip);
@@ -1791,7 +1808,11 @@
val->intval = get_prop_batt_health(chip);
break;
case POWER_SUPPLY_PROP_PRESENT:
- val->intval = get_prop_batt_present(chip);
+ rc = get_prop_batt_present(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
@@ -1803,31 +1824,53 @@
val->intval = chip->min_voltage_mv * 1000;
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = get_prop_battery_uvolts(chip);
+ rc = get_prop_battery_uvolts(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = get_prop_batt_capacity(chip);
+ rc = get_prop_batt_capacity(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = get_prop_batt_current(chip);
+ rc = get_prop_batt_current(chip, &value);
+ if (!rc)
+ val->intval = value;
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
- val->intval = get_prop_batt_current_max(chip);
+ rc = get_prop_batt_current_max(chip, &value);
+ if (!rc)
+ val->intval = value;
break;
case POWER_SUPPLY_PROP_TEMP:
- val->intval = get_prop_batt_temp(chip);
+ rc = get_prop_batt_temp(chip, &value);
+ if (!rc)
+ val->intval = value;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
- val->intval = get_prop_batt_fcc(chip);
+ rc = get_prop_batt_fcc(chip);
+ if (rc >= 0) {
+ val->intval = rc;
+ rc = 0;
+ }
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
- val->intval = get_prop_batt_charge_now(chip);
+ rc = get_prop_batt_charge_now(chip, &value);
+ if (!rc) {
+ val->intval = value;
+ rc = 0;
+ }
break;
default:
- return -EINVAL;
+ rc = -EINVAL;
}
- return 0;
+ return rc;
}
static void (*notify_vbus_state_func_ptr)(int);
@@ -2197,11 +2240,17 @@
int pm8921_batt_temperature(void)
{
+ int temp = 0, rc = 0;
if (!the_chip) {
pr_err("called before init\n");
return -EINVAL;
}
- return get_prop_batt_temp(the_chip);
+ rc = get_prop_batt_temp(the_chip, &temp);
+ if (rc) {
+ pr_err("Unable to read temperature");
+ return rc;
+ }
+ return temp;
}
static void handle_usb_insertion_removal(struct pm8921_chg_chip *chip)
@@ -2735,12 +2784,11 @@
/* No charger active */
if (!(is_usb_chg_plugged_in(chip)
&& !(is_dc_chg_plugged_in(chip)))) {
+ get_prop_batt_current(chip, &ibat);
pr_debug(
"Stop: chg removed reg_loop = %d, fsm = %d ibat = %d\n",
pm_chg_get_regulation_loop(chip),
- pm_chg_get_fsm_state(chip),
- get_prop_batt_current(chip)
- );
+ pm_chg_get_fsm_state(chip), ibat);
return;
} else {
goto check_again_later;
@@ -2767,9 +2815,9 @@
reg_loop = pm_chg_get_regulation_loop(chip);
pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
- ibat = get_prop_batt_current(chip);
+ rc = get_prop_batt_current(chip, &ibat);
if ((reg_loop & VIN_ACTIVE_BIT) && !chip->disable_chg_rmvl_wrkarnd) {
- if (ibat > 0) {
+ if (ibat > 0 && !rc) {
pr_debug("revboost ibat = %d fsm = %d loop = 0x%x\n",
ibat, pm_chg_get_fsm_state(chip), reg_loop);
attempt_reverse_boost_fix(chip);
@@ -3245,9 +3293,9 @@
static void check_temp_thresholds(struct pm8921_chg_chip *chip)
{
- int temp = 0;
+ int temp = 0, rc;
- temp = get_prop_batt_temp(chip);
+ rc = get_prop_batt_temp(chip, &temp);
pr_debug("temp = %d, warm_thr_temp = %d, cool_thr_temp = %d\n",
temp, chip->warm_temp_dc,
chip->cool_temp_dc);
@@ -3468,7 +3516,11 @@
return;
}
- decidegc = get_prop_batt_temp(chip);
+ rc = get_prop_batt_temp(chip, &decidegc);
+ if (rc) {
+ pr_info("Failed to read temperature\n");
+ goto fail_btc_temp;
+ }
pr_debug("temp=%d\n", decidegc);
@@ -3510,6 +3562,7 @@
return;
}
+fail_btc_temp:
rc = pm_chg_override_hot(chip, 0);
if (rc)
pr_err("Couldnt write 0 to hot comp\n");