Loading drivers/power/qcom-charger/fg-core.h +2 −0 Original line number Diff line number Diff line Loading @@ -237,9 +237,11 @@ struct fg_chip { int nom_cap_uah; int status; int prev_status; int last_soc; bool profile_available; bool profile_loaded; bool battery_missing; bool fg_restarting; struct completion soc_update; struct completion soc_ready; struct delayed_work profile_load_work; Loading drivers/power/qcom-charger/qpnp-fg-gen3.c +95 −24 Original line number Diff line number Diff line Loading @@ -279,6 +279,7 @@ module_param_named( sram_dump, fg_sram_dump, bool, S_IRUSR | S_IWUSR ); static int fg_restart; /* All getters HERE */ Loading Loading @@ -999,12 +1000,57 @@ static bool is_profile_load_required(struct fg_chip *chip) } #define SOC_READY_WAIT_MS 2000 static int __fg_restart(struct fg_chip *chip) { int rc, msoc; bool tried_again = false; rc = fg_get_prop_capacity(chip, &msoc); if (rc < 0) { pr_err("Error in getting capacity, rc=%d\n", rc); return rc; } chip->last_soc = msoc; chip->fg_restarting = true; reinit_completion(&chip->soc_ready); rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, RESTART_GO_BIT); if (rc < 0) { pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); goto out; } wait: rc = wait_for_completion_interruptible_timeout(&chip->soc_ready, msecs_to_jiffies(SOC_READY_WAIT_MS)); /* If we were interrupted wait again one more time. */ if (rc == -ERESTARTSYS && !tried_again) { tried_again = true; goto wait; } else if (rc <= 0) { pr_err("wait for soc_ready timed out rc=%d\n", rc); goto out; } rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0); if (rc < 0) { pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); goto out; } out: chip->fg_restarting = false; return rc; } 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; Loading @@ -1029,24 +1075,9 @@ static void profile_load_work(struct work_struct *work) goto out; } rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, RESTART_GO_BIT); rc = __fg_restart(chip); if (rc < 0) { pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); goto out; } wait: rc = wait_for_completion_interruptible_timeout(&chip->soc_ready, msecs_to_jiffies(SOC_READY_WAIT_MS)); /* If we were interrupted wait again one more time. */ if (rc == -ERESTARTSYS && !tried_again) { tried_again = true; goto wait; } else if (rc <= 0) { pr_err("wait for soc_ready timed out rc=%d\n", rc); pr_err("Error in restarting FG, rc=%d\n", rc); goto out; } Loading @@ -1061,7 +1092,6 @@ wait: goto out; } fg_dbg(chip, FG_STATUS, "profile loaded successfully"); done: rc = fg_sram_read(chip, NOM_CAP_WORD, NOM_CAP_OFFSET, buf, 2, FG_IMA_DEFAULT); Loading @@ -1073,14 +1103,52 @@ done: chip->nom_cap_uah = (int)(buf[0] | buf[1] << 8) * 1000; chip->profile_loaded = true; fg_dbg(chip, FG_STATUS, "profile loaded successfully"); out: vote(chip->awake_votable, PROFILE_LOAD, false, 0); rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0); if (rc < 0) pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); } static int fg_restart_sysfs(const char *val, const struct kernel_param *kp) { int rc; struct power_supply *bms_psy; struct fg_chip *chip; rc = param_set_int(val, kp); if (rc) { pr_err("Unable to set fg_restart: %d\n", rc); return rc; } if (fg_restart != 1) { pr_err("Bad value %d\n", fg_restart); return -EINVAL; } bms_psy = power_supply_get_by_name("bms"); if (!bms_psy) { pr_err("bms psy not found\n"); return 0; } chip = power_supply_get_drvdata(bms_psy); rc = __fg_restart(chip); if (rc < 0) { pr_err("Error in restarting FG, rc=%d\n", rc); return rc; } pr_info("FG restart done\n"); return rc; } static struct kernel_param_ops fg_restart_ops = { .set = fg_restart_sysfs, .get = param_get_int, }; module_param_cb(restart, &fg_restart_ops, &fg_restart, 0644); /* PSY CALLBACKS STAY HERE */ static int fg_psy_get_property(struct power_supply *psy, Loading @@ -1092,6 +1160,9 @@ static int fg_psy_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CAPACITY: if (chip->fg_restarting) pval->intval = chip->last_soc; else rc = fg_get_prop_capacity(chip, &pval->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: Loading Loading
drivers/power/qcom-charger/fg-core.h +2 −0 Original line number Diff line number Diff line Loading @@ -237,9 +237,11 @@ struct fg_chip { int nom_cap_uah; int status; int prev_status; int last_soc; bool profile_available; bool profile_loaded; bool battery_missing; bool fg_restarting; struct completion soc_update; struct completion soc_ready; struct delayed_work profile_load_work; Loading
drivers/power/qcom-charger/qpnp-fg-gen3.c +95 −24 Original line number Diff line number Diff line Loading @@ -279,6 +279,7 @@ module_param_named( sram_dump, fg_sram_dump, bool, S_IRUSR | S_IWUSR ); static int fg_restart; /* All getters HERE */ Loading Loading @@ -999,12 +1000,57 @@ static bool is_profile_load_required(struct fg_chip *chip) } #define SOC_READY_WAIT_MS 2000 static int __fg_restart(struct fg_chip *chip) { int rc, msoc; bool tried_again = false; rc = fg_get_prop_capacity(chip, &msoc); if (rc < 0) { pr_err("Error in getting capacity, rc=%d\n", rc); return rc; } chip->last_soc = msoc; chip->fg_restarting = true; reinit_completion(&chip->soc_ready); rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, RESTART_GO_BIT); if (rc < 0) { pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); goto out; } wait: rc = wait_for_completion_interruptible_timeout(&chip->soc_ready, msecs_to_jiffies(SOC_READY_WAIT_MS)); /* If we were interrupted wait again one more time. */ if (rc == -ERESTARTSYS && !tried_again) { tried_again = true; goto wait; } else if (rc <= 0) { pr_err("wait for soc_ready timed out rc=%d\n", rc); goto out; } rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0); if (rc < 0) { pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); goto out; } out: chip->fg_restarting = false; return rc; } 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; Loading @@ -1029,24 +1075,9 @@ static void profile_load_work(struct work_struct *work) goto out; } rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, RESTART_GO_BIT); rc = __fg_restart(chip); if (rc < 0) { pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); goto out; } wait: rc = wait_for_completion_interruptible_timeout(&chip->soc_ready, msecs_to_jiffies(SOC_READY_WAIT_MS)); /* If we were interrupted wait again one more time. */ if (rc == -ERESTARTSYS && !tried_again) { tried_again = true; goto wait; } else if (rc <= 0) { pr_err("wait for soc_ready timed out rc=%d\n", rc); pr_err("Error in restarting FG, rc=%d\n", rc); goto out; } Loading @@ -1061,7 +1092,6 @@ wait: goto out; } fg_dbg(chip, FG_STATUS, "profile loaded successfully"); done: rc = fg_sram_read(chip, NOM_CAP_WORD, NOM_CAP_OFFSET, buf, 2, FG_IMA_DEFAULT); Loading @@ -1073,14 +1103,52 @@ done: chip->nom_cap_uah = (int)(buf[0] | buf[1] << 8) * 1000; chip->profile_loaded = true; fg_dbg(chip, FG_STATUS, "profile loaded successfully"); out: vote(chip->awake_votable, PROFILE_LOAD, false, 0); rc = fg_masked_write(chip, BATT_SOC_RESTART(chip), RESTART_GO_BIT, 0); if (rc < 0) pr_err("Error in writing to %04x, rc=%d\n", BATT_SOC_RESTART(chip), rc); } static int fg_restart_sysfs(const char *val, const struct kernel_param *kp) { int rc; struct power_supply *bms_psy; struct fg_chip *chip; rc = param_set_int(val, kp); if (rc) { pr_err("Unable to set fg_restart: %d\n", rc); return rc; } if (fg_restart != 1) { pr_err("Bad value %d\n", fg_restart); return -EINVAL; } bms_psy = power_supply_get_by_name("bms"); if (!bms_psy) { pr_err("bms psy not found\n"); return 0; } chip = power_supply_get_drvdata(bms_psy); rc = __fg_restart(chip); if (rc < 0) { pr_err("Error in restarting FG, rc=%d\n", rc); return rc; } pr_info("FG restart done\n"); return rc; } static struct kernel_param_ops fg_restart_ops = { .set = fg_restart_sysfs, .get = param_get_int, }; module_param_cb(restart, &fg_restart_ops, &fg_restart, 0644); /* PSY CALLBACKS STAY HERE */ static int fg_psy_get_property(struct power_supply *psy, Loading @@ -1092,6 +1160,9 @@ static int fg_psy_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CAPACITY: if (chip->fg_restarting) pval->intval = chip->last_soc; else rc = fg_get_prop_capacity(chip, &pval->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: Loading