From bda96ffdc06ced1a33b0469e01116d4e1b855dd4 Mon Sep 17 00:00:00 2001 From: Subbaraman Narayanamurthy Date: Mon, 13 Mar 2017 12:50:12 -0700 Subject: [PATCH] qpnp-fg-gen3: Fix adjusting recharge_soc after charge termination After charge termination, recharge SOC might get adjusted, which is fine. However, if the charger is not removed after charge termination and SOC drops further down because of a system load, recharge SOC should not get adjusted again. This can cause recharging not to begin at the intended SOC threshold. Fix this. CRs-Fixed: 2018737 Change-Id: I3595c313f84b2ea8c0459c30f294deb8ac4d2866 Signed-off-by: Subbaraman Narayanamurthy --- drivers/power/supply/qcom/qpnp-fg-gen3.c | 58 ++++++++++++++---------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 39afc235fbc3..5dcd4c36675a 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -1696,6 +1696,9 @@ static int fg_set_recharge_soc(struct fg_chip *chip, int recharge_soc) if (!chip->dt.auto_recharge_soc) return 0; + if (recharge_soc < 0 || recharge_soc > FULL_CAPACITY) + return 0; + fg_encode(chip->sp, FG_SRAM_RECHARGE_SOC_THR, recharge_soc, &buf); rc = fg_sram_write(chip, chip->sp[FG_SRAM_RECHARGE_SOC_THR].addr_word, @@ -1712,46 +1715,55 @@ static int fg_set_recharge_soc(struct fg_chip *chip, int recharge_soc) static int fg_adjust_recharge_soc(struct fg_chip *chip) { int rc, msoc, recharge_soc, new_recharge_soc = 0; + bool recharge_soc_status; if (!chip->dt.auto_recharge_soc) return 0; recharge_soc = chip->dt.recharge_soc_thr; + recharge_soc_status = chip->recharge_soc_adjusted; /* * If the input is present and charging had been terminated, adjust * the recharge SOC threshold based on the monotonic SOC at which * the charge termination had happened. */ - if (is_input_present(chip) && !chip->recharge_soc_adjusted - && chip->charge_done) { - /* Get raw monotonic SOC for calculation */ - rc = fg_get_msoc(chip, &msoc); - if (rc < 0) { - pr_err("Error in getting msoc, rc=%d\n", rc); - return rc; - } + if (is_input_present(chip)) { + if (chip->charge_done) { + if (!chip->recharge_soc_adjusted) { + /* Get raw monotonic SOC for calculation */ + rc = fg_get_msoc(chip, &msoc); + if (rc < 0) { + pr_err("Error in getting msoc, rc=%d\n", + rc); + return rc; + } - /* Adjust the recharge_soc threshold */ - new_recharge_soc = msoc - (FULL_CAPACITY - recharge_soc); - } else if (chip->recharge_soc_adjusted && (!is_input_present(chip) - || chip->health == POWER_SUPPLY_HEALTH_GOOD)) { + /* Adjust the recharge_soc threshold */ + new_recharge_soc = msoc - (FULL_CAPACITY - + recharge_soc); + chip->recharge_soc_adjusted = true; + } else { + /* adjusted already, do nothing */ + return 0; + } + } else { + /* Charging, do nothing */ + return 0; + } + } else { /* Restore the default value */ new_recharge_soc = recharge_soc; + chip->recharge_soc_adjusted = false; } - if (new_recharge_soc > 0 && new_recharge_soc < FULL_CAPACITY) { - rc = fg_set_recharge_soc(chip, new_recharge_soc); - if (rc) { - pr_err("Couldn't set resume SOC for FG, rc=%d\n", rc); - return rc; - } - - chip->recharge_soc_adjusted = (new_recharge_soc != - recharge_soc); - fg_dbg(chip, FG_STATUS, "resume soc set to %d\n", - new_recharge_soc); + rc = fg_set_recharge_soc(chip, new_recharge_soc); + if (rc < 0) { + chip->recharge_soc_adjusted = recharge_soc_status; + pr_err("Couldn't set resume SOC for FG, rc=%d\n", rc); + return rc; } + fg_dbg(chip, FG_STATUS, "resume soc set to %d\n", new_recharge_soc); return 0; }