diff options
author | Subbaraman Narayanamurthy <subbaram@codeaurora.org> | 2016-09-21 12:36:03 -0700 |
---|---|---|
committer | Subbaraman Narayanamurthy <subbaram@codeaurora.org> | 2016-10-10 09:44:04 -0700 |
commit | bd811f3afde01a284c8892dba5a7acecdf56975f (patch) | |
tree | 35459dbd4be292878f40ce1af16172ae0a27d191 /drivers | |
parent | 9435c04228a8117f7acba15169820e27dc8ed398 (diff) |
qpnp-fg-gen3: Add support to configure force battery profile loading
Currently, FG_GEN3 driver loads the battery profile if it finds
out the profile loaded earlier doesn't match with the available
profile. This will be done when the profile integrity bit is
set already. Make this force profile loading as a configurable
parameter through a device tree property.
While at it, add a module parameter to dump the profile contents
conditionally. This will be helpful in debugging.
Change-Id: Ibaff55aa5434ee283e6d597485d193e9e52bb74e
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/power/qcom-charger/fg-core.h | 1 | ||||
-rw-r--r-- | drivers/power/qcom-charger/qpnp-fg-gen3.c | 77 |
2 files changed, 65 insertions, 13 deletions
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h index 24ab83565fc9..e4715fd6fb39 100644 --- a/drivers/power/qcom-charger/fg-core.h +++ b/drivers/power/qcom-charger/fg-core.h @@ -181,6 +181,7 @@ struct fg_dt_props { int esr_timer_charging; int esr_timer_awake; int esr_timer_asleep; + bool force_load_profile; }; /* parameters from battery profile */ diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c index ac24ad9486d9..76c26ca7c800 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c @@ -274,6 +274,12 @@ module_param_named( sram_update_period_ms, fg_sram_update_period_ms, int, S_IRUSR | S_IWUSR ); +static bool fg_sram_dump; +module_param_named( + sram_dump, fg_sram_dump, bool, S_IRUSR | S_IWUSR +); + + /* All getters HERE */ static int fg_decode_value_16b(struct fg_sram_param *sp, @@ -929,40 +935,82 @@ static int fg_get_cycle_count(struct fg_chip *chip) return count; } -#define SOC_READY_WAIT_MS 2000 -static void profile_load_work(struct work_struct *work) +static void dump_sram(u8 *buf, int len) +{ + int i; + char str[16]; + + for (i = 0; i < len; i += 4) { + str[0] = '\0'; + fill_string(str, sizeof(str), buf + i, 4); + pr_info("%03d %s\n", PROFILE_LOAD_WORD + (i / 4), str); + } +} + +static bool is_profile_load_required(struct fg_chip *chip) { - struct fg_chip *chip = container_of(work, - struct fg_chip, - profile_load_work.work); - int rc; u8 buf[PROFILE_COMP_LEN], val; - bool tried_again = false, profiles_same = false; + bool profiles_same = false; + int rc; rc = fg_sram_read(chip, PROFILE_INTEGRITY_WORD, PROFILE_INTEGRITY_OFFSET, &val, 1, FG_IMA_DEFAULT); if (rc < 0) { pr_err("failed to read profile integrity rc=%d\n", rc); - return; + return false; } - vote(chip->awake_votable, PROFILE_LOAD, true, 0); + /* Check if integrity bit is set */ if (val == 0x01) { fg_dbg(chip, FG_STATUS, "Battery profile integrity bit is set\n"); rc = fg_sram_read(chip, PROFILE_LOAD_WORD, PROFILE_LOAD_OFFSET, buf, PROFILE_COMP_LEN, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in reading battery profile, rc:%d\n", rc); - goto out; + return false; } profiles_same = memcmp(chip->batt_profile, buf, PROFILE_COMP_LEN) == 0; if (profiles_same) { - fg_dbg(chip, FG_STATUS, "Battery profile is same\n"); - goto done; + fg_dbg(chip, FG_STATUS, "Battery profile is same, not loading it\n"); + return false; + } + + if (!chip->dt.force_load_profile) { + pr_warn("Profiles doesn't match, skipping loading it since force_load_profile is disabled\n"); + if (fg_sram_dump) { + pr_info("FG: loaded profile:\n"); + dump_sram(buf, PROFILE_COMP_LEN); + pr_info("FG: available profile:\n"); + dump_sram(chip->batt_profile, PROFILE_LEN); + } + return false; + } + + fg_dbg(chip, FG_STATUS, "Profiles are different, loading the correct one\n"); + } else { + fg_dbg(chip, FG_STATUS, "Profile integrity bit is not set\n"); + if (fg_sram_dump) { + pr_info("FG: profile to be loaded:\n"); + dump_sram(chip->batt_profile, PROFILE_LEN); } - fg_dbg(chip, FG_STATUS, "profiles are different?\n"); } + return true; +} + +#define SOC_READY_WAIT_MS 2000 +static void profile_load_work(struct work_struct *work) +{ + struct fg_chip *chip = container_of(work, + struct fg_chip, + profile_load_work.work); + bool tried_again = false; + u8 buf[2], val; + int rc; + + vote(chip->awake_votable, PROFILE_LOAD, true, 0); + if (!is_profile_load_required(chip)) + goto done; clear_cycle_counter(chip); fg_dbg(chip, FG_STATUS, "profile loading started\n"); @@ -1783,6 +1831,9 @@ static int fg_parse_dt(struct fg_chip *chip) if (chip->cyc_ctr.en) chip->cyc_ctr.id = 1; + chip->dt.force_load_profile = of_property_read_bool(node, + "qcom,fg-force-load-profile"); + return 0; } |