power: smb-lib: Rearrange BOOST_BACK voting logic

The BOOST_BACK USB-ICL voter needs to be removed in the
following conditions -

1. VBUS falling path during PD hard-reset
2. typeC removal
3. False boost-back detected

For (1) and (2) - remove the boost_back vote in the usbin_handler
and typec_removal path. For (3) add a worker which removes the
boost_back vote after the boost-back condition is detected. The
delay is sufficient to recover from both a valid and an incorrectly
detected boost-back condition.

CRs-Fixed: 2051908
Change-Id: I9d1d04f392bb6040b0565510ff7d1032bb036de2
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
This commit is contained in:
Anirudh Ghayal 2017-05-26 09:41:25 +05:30 committed by Ashay Jaiswal
parent 560a996da5
commit f11fd649ff
2 changed files with 48 additions and 2 deletions

View file

@ -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();

View file

@ -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;