Merge "qpnp-fg-gen3: fix a possible wake source count leak"

This commit is contained in:
Linux Build Service Account 2016-12-19 00:44:54 -08:00 committed by Gerrit - the friendly Code Review server
commit 7dd05f7446
3 changed files with 109 additions and 5 deletions

View file

@ -266,6 +266,13 @@ First Level Node - FG Gen3 device
is specified to make it fully functional. Value has no
unit. Allowed range is 0 to 62200 in micro units.
- qcom,fg-rconn-mohms
Usage: optional
Value type: <u32>
Definition: Battery connector resistance (Rconn) in milliohms. If Rconn
is specified, then ESR to Rslow scaling factors will be
updated to account it for an accurate ESR.
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================

View file

@ -211,10 +211,10 @@ struct fg_dt_props {
int recharge_soc_thr;
int recharge_volt_thr_mv;
int rsense_sel;
int jeita_thresholds[NUM_JEITA_LEVELS];
int esr_timer_charging;
int esr_timer_awake;
int esr_timer_asleep;
int rconn_mohms;
int cl_start_soc;
int cl_max_temp;
int cl_min_temp;
@ -224,6 +224,7 @@ struct fg_dt_props {
int cl_min_cap_limit;
int jeita_hyst_temp;
int batt_temp_delta;
int jeita_thresholds[NUM_JEITA_LEVELS];
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
int ki_coeff_hi_dischg[KI_COEFF_SOC_LEVELS];

View file

@ -62,6 +62,10 @@
#define ESR_TIMER_CHG_INIT_OFFSET 2
#define PROFILE_LOAD_WORD 24
#define PROFILE_LOAD_OFFSET 0
#define ESR_RSLOW_DISCHG_WORD 34
#define ESR_RSLOW_DISCHG_OFFSET 0
#define ESR_RSLOW_CHG_WORD 51
#define ESR_RSLOW_CHG_OFFSET 0
#define NOM_CAP_WORD 58
#define NOM_CAP_OFFSET 0
#define ACT_BATT_CAP_BKUP_WORD 74
@ -69,6 +73,7 @@
#define CYCLE_COUNT_WORD 75
#define CYCLE_COUNT_OFFSET 0
#define PROFILE_INTEGRITY_WORD 79
#define SW_CONFIG_OFFSET 0
#define PROFILE_INTEGRITY_OFFSET 3
#define BATT_SOC_WORD 91
#define BATT_SOC_OFFSET 0
@ -564,21 +569,21 @@ static int fg_get_battery_esr(struct fg_chip *chip, int *val)
static int fg_get_battery_resistance(struct fg_chip *chip, int *val)
{
int rc, esr, rslow;
int rc, esr_uohms, rslow_uohms;
rc = fg_get_battery_esr(chip, &esr);
rc = fg_get_battery_esr(chip, &esr_uohms);
if (rc < 0) {
pr_err("failed to get ESR, rc=%d\n", rc);
return rc;
}
rc = fg_get_sram_prop(chip, FG_SRAM_RSLOW, &rslow);
rc = fg_get_sram_prop(chip, FG_SRAM_RSLOW, &rslow_uohms);
if (rc < 0) {
pr_err("failed to get Rslow, rc=%d\n", rc);
return rc;
}
*val = esr + rslow;
*val = esr_uohms + rslow_uohms;
return 0;
}
@ -1407,6 +1412,80 @@ static int fg_charge_full_update(struct fg_chip *chip)
return 0;
}
#define RCONN_CONFIG_BIT BIT(0)
static int fg_rconn_config(struct fg_chip *chip)
{
int rc, esr_uohms;
u64 scaling_factor;
u32 val = 0;
rc = fg_sram_read(chip, PROFILE_INTEGRITY_WORD,
SW_CONFIG_OFFSET, (u8 *)&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in reading SW_CONFIG_OFFSET, rc=%d\n", rc);
return rc;
}
if (val & RCONN_CONFIG_BIT) {
fg_dbg(chip, FG_STATUS, "Rconn already configured: %x\n", val);
return 0;
}
rc = fg_get_battery_esr(chip, &esr_uohms);
if (rc < 0) {
pr_err("failed to get ESR, rc=%d\n", rc);
return rc;
}
scaling_factor = div64_u64((u64)esr_uohms * 1000,
esr_uohms + (chip->dt.rconn_mohms * 1000));
rc = fg_sram_read(chip, ESR_RSLOW_CHG_WORD,
ESR_RSLOW_CHG_OFFSET, (u8 *)&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in reading ESR_RSLOW_CHG_OFFSET, rc=%d\n", rc);
return rc;
}
val *= scaling_factor;
do_div(val, 1000);
rc = fg_sram_write(chip, ESR_RSLOW_CHG_WORD,
ESR_RSLOW_CHG_OFFSET, (u8 *)&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing ESR_RSLOW_CHG_OFFSET, rc=%d\n", rc);
return rc;
}
fg_dbg(chip, FG_STATUS, "esr_rslow_chg modified to %x\n", val & 0xFF);
rc = fg_sram_read(chip, ESR_RSLOW_DISCHG_WORD,
ESR_RSLOW_DISCHG_OFFSET, (u8 *)&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in reading ESR_RSLOW_DISCHG_OFFSET, rc=%d\n", rc);
return rc;
}
val *= scaling_factor;
do_div(val, 1000);
rc = fg_sram_write(chip, ESR_RSLOW_DISCHG_WORD,
ESR_RSLOW_DISCHG_OFFSET, (u8 *)&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing ESR_RSLOW_DISCHG_OFFSET, rc=%d\n", rc);
return rc;
}
fg_dbg(chip, FG_STATUS, "esr_rslow_dischg modified to %x\n",
val & 0xFF);
val = RCONN_CONFIG_BIT;
rc = fg_sram_write(chip, PROFILE_INTEGRITY_WORD,
SW_CONFIG_OFFSET, (u8 *)&val, 1, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing SW_CONFIG_OFFSET, rc=%d\n", rc);
return rc;
}
return 0;
}
static int fg_set_recharge_soc(struct fg_chip *chip, int recharge_soc)
{
u8 buf[4];
@ -2369,6 +2448,9 @@ static int fg_notifier_cb(struct notifier_block *nb,
if (event != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
if (work_pending(&chip->status_change_work))
return NOTIFY_OK;
if ((strcmp(psy->desc->name, "battery") == 0)
|| (strcmp(psy->desc->name, "usb") == 0)) {
/*
@ -2614,6 +2696,14 @@ static int fg_hw_init(struct fg_chip *chip)
return rc;
}
if (chip->dt.rconn_mohms > 0) {
rc = fg_rconn_config(chip);
if (rc < 0) {
pr_err("Error in configuring Rconn, rc=%d\n", rc);
return rc;
}
}
return 0;
}
@ -3282,6 +3372,12 @@ static int fg_parse_dt(struct fg_chip *chip)
if (rc < 0)
pr_err("Error in parsing Ki coefficients, rc=%d\n", rc);
rc = of_property_read_u32(node, "qcom,fg-rconn-mohms", &temp);
if (rc < 0)
chip->dt.rconn_mohms = -EINVAL;
else
chip->dt.rconn_mohms = temp;
return 0;
}