summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHarry Yang <harryy@codeaurora.org>2017-03-13 16:51:43 -0700
committerHarry Yang <harryy@codeaurora.org>2017-03-21 12:47:48 -0700
commitde945810ad80596bb43995f9e8ade6eb4d8ad64e (patch)
tree5e8cb386588a4386dc28440473541a1370bc3c45 /drivers
parent25ed77f5bb9a1af7e4635c5aa91505fae041ea27 (diff)
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: Harry Yang <harryy@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c11
-rw-r--r--drivers/power/supply/qcom/smb-lib.c36
-rw-r--r--drivers/power/supply/qcom/smb-lib.h2
3 files changed, 49 insertions, 0 deletions
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 771d1cd32714..9b7ccf9f5221 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -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);
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 7d2e00dc934b..b84bac016111 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -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;
}
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index de236164e6b2..c548c1333134 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -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;