Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36feefef authored by Anirudh Ghayal's avatar Anirudh Ghayal Committed by Abhijeet Dharmapurikar
Browse files

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: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent b9b2d2f8
Loading
Loading
Loading
Loading
+47 −2
Original line number Diff line number Diff line
@@ -631,6 +631,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);

@@ -3142,10 +3153,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",
@@ -3582,6 +3596,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);
@@ -3802,6 +3827,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;
@@ -3829,6 +3864,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;
@@ -4483,6 +4526,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;

@@ -4538,6 +4582,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();
+1 −0
Original line number Diff line number Diff line
@@ -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;