diff options
| author | Abhijeet Dharmapurikar <adharmap@codeaurora.org> | 2017-07-07 18:30:54 -0700 |
|---|---|---|
| committer | Abhijeet Dharmapurikar <adharmap@codeaurora.org> | 2017-07-11 16:14:32 -0700 |
| commit | fed0617ff29419453762dae21be7daa3bbaa9e40 (patch) | |
| tree | 01d6178218995a2e63843c200a66bc383ea6547e | |
| parent | d6f171ce52ce47aa18c80145298c9237fb577e24 (diff) | |
smb-lib: fix usbin_icl_change interrupt storm
We observed an interrupt storm on that interrupt
even after the usb path is suspended.
So keep this interrupt disabled as long as the usb
path is suspended.
Note that since the current limit votes can come in
prior to interrupt registration, rerun the election
on the votable after interrupts are registered.
Change-Id: Ib43b071b7b0decf8e50d27d585bea04b727f9475
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
| -rw-r--r-- | drivers/power/supply/qcom/qpnp-smb2.c | 8 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 17 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.h | 1 |
3 files changed, 24 insertions, 2 deletions
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 0908eea3b186..7b7f991ecba9 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1847,6 +1847,12 @@ static int smb2_post_init(struct smb2 *chip) struct smb_charger *chg = &chip->chg; int rc; + /* In case the usb path is suspended, we would have missed disabling + * the icl change interrupt because the interrupt could have been + * not requested + */ + rerun_election(chg->usb_icl_votable); + /* configure power role for dual-role */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, TYPEC_POWER_ROLE_CMD_MASK, 0); @@ -2196,6 +2202,8 @@ static int smb2_request_interrupts(struct smb2 *chip) return rc; } } + if (chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq) + chg->usb_icl_change_irq_enabled = true; return rc; } diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 16db425514c3..64ed53185e88 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -427,6 +427,14 @@ static int step_charge_soc_update(struct smb_charger *chg, int capacity) int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend) { int rc = 0; + int irq = chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq; + + if (suspend && irq) { + if (chg->usb_icl_change_irq_enabled) { + disable_irq_nosync(irq); + chg->usb_icl_change_irq_enabled = false; + } + } rc = smblib_masked_write(chg, USBIN_CMD_IL_REG, USBIN_SUSPEND_BIT, suspend ? USBIN_SUSPEND_BIT : 0); @@ -434,6 +442,13 @@ int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend) smblib_err(chg, "Couldn't write %s to USBIN_SUSPEND_BIT rc=%d\n", suspend ? "suspend" : "resume", rc); + if (!suspend && irq) { + if (!chg->usb_icl_change_irq_enabled) { + enable_irq(irq); + chg->usb_icl_change_irq_enabled = true; + } + } + return rc; } @@ -885,7 +900,6 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) if (icl_ua < USBIN_25MA) return smblib_set_usb_suspend(chg, true); - disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq); if (icl_ua == INT_MAX) goto override_suspend_config; @@ -943,7 +957,6 @@ override_suspend_config: } enable_icl_changed_interrupt: - enable_irq(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq); return rc; } diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index c97b84c34084..18714827b8d2 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -328,6 +328,7 @@ struct smb_charger { int fake_input_current_limited; bool pr_swap_in_progress; int typec_mode; + int usb_icl_change_irq_enabled; /* workaround flag */ u32 wa_flags; |
