power: qpnp-bms: disable sw_cc_thresh interrupt after it fires
Currently in the BMS driver, when the software coulomb counter threshold
is reached, only a soc recalculation is scheduled in the irq handler.
This can cause issues where the BMS hardware fires another sw_cc_thresh
irq because the coulomb counter is still over threshold.
Instead, disable the sw_cc_thresh irq when it is handled and renable it
after adjusting the software coulomb counter threshold registers.
Change-Id: I70791fdae1835c8d24b7c045831d22fe86e83fdb
Signed-off-by: Xiaozhe Shi <xiaozhes@codeaurora.org>
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 3fe1ca8..bbfbf07 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -2271,6 +2271,8 @@
qpnp_write_wrapper(chip, (u8 *)&ocv_raw,
chip->base + BMS1_OCV_THR0, 2);
+ enable_bms_irq(&chip->ocv_thr_irq);
+ enable_bms_irq(&chip->sw_cc_thr_irq);
pr_debug("current sw_cc_raw = 0x%llx, current ocv = 0x%hx\n",
current_shdw_cc_raw, (uint16_t)current_ocv_raw);
pr_debug("target_cc_uah = %lld, raw64 = 0x%llx, raw 36 = 0x%llx, ocv_raw = 0x%hx\n",
@@ -2402,9 +2404,13 @@
* If the battery is full, configure the cc threshold so the system
* wakes up after SoC changes
*/
- if (is_battery_full(chip))
+ if (is_battery_full(chip)) {
configure_soc_wakeup(chip, ¶ms,
batt_temp, bound_soc(new_calculated_soc - 1));
+ } else {
+ disable_bms_irq(&chip->ocv_thr_irq);
+ disable_bms_irq(&chip->sw_cc_thr_irq);
+ }
done_calculating:
mutex_lock(&chip->last_soc_mutex);
previous_soc = chip->calculated_soc;
@@ -3246,8 +3252,6 @@
if (status == POWER_SUPPLY_STATUS_FULL) {
pr_debug("battery full\n");
- enable_bms_irq(&chip->ocv_thr_irq);
- enable_bms_irq(&chip->sw_cc_thr_irq);
recalculate_soc(chip);
} else if (chip->battery_status
== POWER_SUPPLY_STATUS_FULL) {
@@ -3546,6 +3550,7 @@
struct qpnp_bms_chip *chip = _chip;
pr_debug("sw_cc_thr irq triggered\n");
+ disable_bms_irq(&chip->sw_cc_thr_irq);
bms_stay_awake(&chip->soc_wake_source);
schedule_work(&chip->recalc_work);
return IRQ_HANDLED;