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

Commit de945810 authored by Harry Yang's avatar Harry Yang
Browse files

qcom: smblib: Only enable hdc and icl irqs on QC/PD chargers



Weak chargers may trigger high duty cycle and input current limiting
irq storms, so only enable them on QC2/3 and PD chargers.

CRs-Fixed: 2018322
Change-Id: I9e54305b74876e0fd15751614964c0ec9bacbfae
Signed-off-by: default avatarHarry Yang <harryy@codeaurora.org>
parent 25ed77f5
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -1616,6 +1616,15 @@ static int smb2_init_hw(struct smb2 *chip)
	return rc;
}

static int smb2_post_init(struct smb2 *chip)
{
	struct smb_charger *chg = &chip->chg;

	rerun_election(chg->usb_irq_enable_votable);

	return 0;
}

static int smb2_chg_config_init(struct smb2 *chip)
{
	struct smb_charger *chg = &chip->chg;
@@ -2145,6 +2154,8 @@ static int smb2_probe(struct platform_device *pdev)
		goto cleanup;
	}

	smb2_post_init(chip);

	smb2_create_debugfs(chip);

	rc = smblib_get_prop_usb_present(chg, &val);
+36 −0
Original line number Diff line number Diff line
@@ -1109,6 +1109,26 @@ static int smblib_hvdcp_hw_inov_dis_vote_callback(struct votable *votable,
	return rc;
}

static int smblib_usb_irq_enable_vote_callback(struct votable *votable,
				void *data, int enable, const char *client)
{
	struct smb_charger *chg = data;

	if (!chg->irq_info[INPUT_CURRENT_LIMIT_IRQ].irq ||
				!chg->irq_info[HIGH_DUTY_CYCLE_IRQ].irq)
		return 0;

	if (enable) {
		enable_irq(chg->irq_info[INPUT_CURRENT_LIMIT_IRQ].irq);
		enable_irq(chg->irq_info[HIGH_DUTY_CYCLE_IRQ].irq);
	} else {
		disable_irq(chg->irq_info[INPUT_CURRENT_LIMIT_IRQ].irq);
		disable_irq(chg->irq_info[HIGH_DUTY_CYCLE_IRQ].irq);
	}

	return 0;
}

/*******************
 * VCONN REGULATOR *
 * *****************/
@@ -2470,6 +2490,7 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,

	vote(chg->apsd_disable_votable, PD_VOTER, pd_active, 0);
	vote(chg->pd_allowed_votable, PD_VOTER, pd_active, 0);
	vote(chg->usb_irq_enable_votable, PD_VOTER, pd_active, 0);

	/*
	 * VCONN_EN_ORIENTATION_BIT controls whether to use CC1 or CC2 line
@@ -3304,6 +3325,10 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg,
			/* could be a legacy cable, try doing hvdcp */
			try_rerun_apsd_for_hvdcp(chg);

		/* enable HDC and ICL irq for QC2/3 charger */
		if (qc_charger)
			vote(chg->usb_irq_enable_votable, QC_VOTER, true, 0);

		/*
		 * HVDCP detection timeout done
		 * If adapter is not QC2.0/QC3.0 - it is a plain old DCP.
@@ -3554,6 +3579,8 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
	vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0);
	vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0);
	vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0);
	vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0);
	vote(chg->usb_irq_enable_votable, QC_VOTER, false, 0);

	/* reset votes from vbus_cc_short */
	vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
@@ -4236,6 +4263,15 @@ static int smblib_create_votables(struct smb_charger *chg)
		return rc;
	}

	chg->usb_irq_enable_votable = create_votable("USB_IRQ_DISABLE",
					VOTE_SET_ANY,
					smblib_usb_irq_enable_vote_callback,
					chg);
	if (IS_ERR(chg->usb_irq_enable_votable)) {
		rc = PTR_ERR(chg->usb_irq_enable_votable);
		return rc;
	}

	return rc;
}

+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ enum print_reason {
#define USER_VOTER			"USER_VOTER"
#define PD_VOTER			"PD_VOTER"
#define DCP_VOTER			"DCP_VOTER"
#define QC_VOTER			"QC_VOTER"
#define PL_USBIN_USBIN_VOTER		"PL_USBIN_USBIN_VOTER"
#define USB_PSY_VOTER			"USB_PSY_VOTER"
#define PL_TAPER_WORK_RUNNING_VOTER	"PL_TAPER_WORK_RUNNING_VOTER"
@@ -272,6 +273,7 @@ struct smb_charger {
	struct votable		*hvdcp_enable_votable;
	struct votable		*apsd_disable_votable;
	struct votable		*hvdcp_hw_inov_dis_votable;
	struct votable		*usb_irq_enable_votable;

	/* work */
	struct work_struct	bms_update_work;