diff options
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 49 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.h | 1 |
2 files changed, 48 insertions, 2 deletions
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index ef62631f6d98..49a5a17a521b 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -632,6 +632,17 @@ static void smblib_uusb_removal(struct smb_charger *chg) int rc; cancel_delayed_work_sync(&chg->pl_enable_work); + + if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) { + smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n"); + rc = regulator_disable(chg->dpdm_reg); + if (rc < 0) + smblib_err(chg, "Couldn't disable dpdm regulator rc=%d\n", + rc); + } + + if (chg->wa_flags & BOOST_BACK_WA) + vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); @@ -3136,10 +3147,13 @@ void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); - if (vbus_rising) + if (vbus_rising) { smblib_cc2_sink_removal_exit(chg); - else + } else { smblib_cc2_sink_removal_enter(chg); + if (chg->wa_flags & BOOST_BACK_WA) + vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0); + } power_supply_changed(chg->usb_psy); smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", @@ -3571,6 +3585,17 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) chg->cc2_detach_wa_active = false; + if (chg->dpdm_reg && regulator_is_enabled(chg->dpdm_reg)) { + smblib_dbg(chg, PR_MISC, "disabling DPDM regulator\n"); + rc = regulator_disable(chg->dpdm_reg); + if (rc < 0) + smblib_err(chg, "Couldn't disable dpdm regulator rc=%d\n", + rc); + } + + if (chg->wa_flags & BOOST_BACK_WA) + vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0); + /* reset APSD voters */ vote(chg->apsd_disable_votable, PD_HARD_RESET_VOTER, false, 0); vote(chg->apsd_disable_votable, PD_VOTER, false, 0); @@ -3791,6 +3816,16 @@ irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data) return IRQ_HANDLED; } +static void smblib_bb_removal_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + bb_removal_work.work); + + vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0); + vote(chg->awake_votable, BOOST_BACK_VOTER, false, 0); +} + +#define BOOST_BACK_UNVOTE_DELAY_MS 750 irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data) { struct smb_irq_data *irq_data = data; @@ -3818,6 +3853,14 @@ irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data) if (is_storming(&irq_data->storm_data)) { smblib_err(chg, "Reverse boost detected: voting 0mA to suspend input\n"); vote(chg->usb_icl_votable, BOOST_BACK_VOTER, true, 0); + vote(chg->awake_votable, BOOST_BACK_VOTER, true, 0); + /* + * Remove the boost-back vote after a delay, to avoid + * permanently suspending the input if the boost-back condition + * is unintentionally hit. + */ + schedule_delayed_work(&chg->bb_removal_work, + msecs_to_jiffies(BOOST_BACK_UNVOTE_DELAY_MS)); } return IRQ_HANDLED; @@ -4472,6 +4515,7 @@ int smblib_init(struct smb_charger *chg) INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work); INIT_WORK(&chg->legacy_detection_work, smblib_legacy_detection_work); INIT_DELAYED_WORK(&chg->uusb_otg_work, smblib_uusb_otg_work); + INIT_DELAYED_WORK(&chg->bb_removal_work, smblib_bb_removal_work); chg->fake_capacity = -EINVAL; chg->fake_input_current_limited = -EINVAL; @@ -4527,6 +4571,7 @@ int smblib_deinit(struct smb_charger *chg) cancel_delayed_work_sync(&chg->pl_enable_work); cancel_work_sync(&chg->legacy_detection_work); cancel_delayed_work_sync(&chg->uusb_otg_work); + cancel_delayed_work_sync(&chg->bb_removal_work); power_supply_unreg_notifier(&chg->nb); smblib_destroy_votables(chg); qcom_batt_deinit(); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 8ba0a1dfe19f..a428b35f9493 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -292,6 +292,7 @@ struct smb_charger { struct delayed_work pl_enable_work; struct work_struct legacy_detection_work; struct delayed_work uusb_otg_work; + struct delayed_work bb_removal_work; /* cached status */ int voltage_min_uv; |
