power: qpnp-fg-gen3: synchronize ESR extraction control configuration

Currently, ESR extraction control is configured from two paths.
First is invoked when Qnovo is enabled or disabled. Second is
invoked when the pulse train is done and ESR measurement is
requested. When the latter is run, there is a sleep time of 1.5
seconds that is essential for allowing FG to do ESR measurement.
However in that time window, if Qnovo is disabled for some reason
then ESR extraction control will be kept disabled unexpectedly.

Fix this by protecting both the paths using a mutex lock as well
as checking for qnovo enable status before disabling ESR
extraction control after measuring ESR.

Change-Id: Ib93539071724a1ce59d198074854a8a9c5fd3ab3
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
Subbaraman Narayanamurthy 2017-09-12 20:19:17 -07:00
parent b86ba37927
commit 4ce690327a
2 changed files with 38 additions and 12 deletions

View file

@ -402,6 +402,7 @@ struct fg_chip {
struct mutex bus_lock;
struct mutex sram_rw_lock;
struct mutex charge_full_lock;
struct mutex qnovo_esr_ctrl_lock;
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
@ -435,6 +436,7 @@ struct fg_chip {
bool esr_flt_cold_temp_en;
bool slope_limit_en;
bool use_ima_single_mode;
bool qnovo_enable;
struct completion soc_update;
struct completion soc_ready;
struct delayed_work profile_load_work;

View file

@ -3297,20 +3297,21 @@ static int fg_force_esr_meas(struct fg_chip *chip)
int rc;
int esr_uohms;
mutex_lock(&chip->qnovo_esr_ctrl_lock);
/* force esr extraction enable */
rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
ESR_EXTRACTION_ENABLE_OFFSET, BIT(0), BIT(0),
FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("failed to enable esr extn rc=%d\n", rc);
return rc;
goto out;
}
rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
LD_REG_CTRL_BIT, 0);
if (rc < 0) {
pr_err("Error in configuring qnovo_cfg rc=%d\n", rc);
return rc;
goto out;
}
rc = fg_masked_write(chip, BATT_INFO_TM_MISC1(chip),
@ -3318,24 +3319,36 @@ static int fg_force_esr_meas(struct fg_chip *chip)
ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT);
if (rc < 0) {
pr_err("Error in configuring force ESR rc=%d\n", rc);
return rc;
goto out;
}
/*
* Release and grab the lock again after 1.5 seconds so that prepare
* callback can succeed if the request comes in between.
*/
mutex_unlock(&chip->qnovo_esr_ctrl_lock);
/* wait 1.5 seconds for hw to measure ESR */
msleep(1500);
mutex_lock(&chip->qnovo_esr_ctrl_lock);
rc = fg_masked_write(chip, BATT_INFO_TM_MISC1(chip),
ESR_REQ_CTL_BIT | ESR_REQ_CTL_EN_BIT,
0);
if (rc < 0) {
pr_err("Error in restoring force ESR rc=%d\n", rc);
return rc;
goto out;
}
/* If qnovo is disabled, then leave ESR extraction enabled */
if (!chip->qnovo_enable)
goto done;
rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
LD_REG_CTRL_BIT, LD_REG_CTRL_BIT);
if (rc < 0) {
pr_err("Error in restoring qnovo_cfg rc=%d\n", rc);
return rc;
goto out;
}
/* force esr extraction disable */
@ -3344,36 +3357,46 @@ static int fg_force_esr_meas(struct fg_chip *chip)
FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("failed to disable esr extn rc=%d\n", rc);
return rc;
goto out;
}
done:
fg_get_battery_resistance(chip, &esr_uohms);
fg_dbg(chip, FG_STATUS, "ESR uohms = %d\n", esr_uohms);
out:
mutex_unlock(&chip->qnovo_esr_ctrl_lock);
return rc;
}
static int fg_prepare_for_qnovo(struct fg_chip *chip, int qnovo_enable)
{
int rc;
int rc = 0;
mutex_lock(&chip->qnovo_esr_ctrl_lock);
/* force esr extraction disable when qnovo enables */
rc = fg_sram_masked_write(chip, ESR_EXTRACTION_ENABLE_WORD,
ESR_EXTRACTION_ENABLE_OFFSET,
BIT(0), qnovo_enable ? 0 : BIT(0),
FG_IMA_DEFAULT);
if (rc < 0)
if (rc < 0) {
pr_err("Error in configuring esr extraction rc=%d\n", rc);
goto out;
}
rc = fg_masked_write(chip, BATT_INFO_QNOVO_CFG(chip),
LD_REG_CTRL_BIT,
qnovo_enable ? LD_REG_CTRL_BIT : 0);
if (rc < 0) {
pr_err("Error in configuring qnovo_cfg rc=%d\n", rc);
return rc;
goto out;
}
fg_dbg(chip, FG_STATUS, "Prepared for Qnovo\n");
return 0;
fg_dbg(chip, FG_STATUS, "%s for Qnovo\n",
qnovo_enable ? "Prepared" : "Unprepared");
chip->qnovo_enable = qnovo_enable;
out:
mutex_unlock(&chip->qnovo_esr_ctrl_lock);
return rc;
}
static void ttf_work(struct work_struct *work)
@ -5002,6 +5025,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
mutex_init(&chip->cl.lock);
mutex_init(&chip->ttf.lock);
mutex_init(&chip->charge_full_lock);
mutex_init(&chip->qnovo_esr_ctrl_lock);
init_completion(&chip->soc_update);
init_completion(&chip->soc_ready);
INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);