Merge "qpnp-smb2: fix reverse boost when input is removed"

This commit is contained in:
Linux Build Service Account 2016-11-08 11:19:01 -08:00 committed by Gerrit - the friendly Code Review server
commit d64b4912b6
3 changed files with 56 additions and 10 deletions

View file

@ -1241,6 +1241,7 @@ static int smb2_setup_wa_flags(struct smb2 *chip)
switch (pmic_rev_id->pmic_subtype) {
case PMICOBALT_SUBTYPE:
chip->chg.wa_flags |= BOOST_BACK_WA;
if (pmic_rev_id->rev4 == PMICOBALT_V1P1_REV4) /* PMI rev 1.1 */
chg->wa_flags |= QC_CHARGER_DETECTION_WA_BIT;
break;
@ -1451,7 +1452,8 @@ static struct smb2_irq_info smb2_irqs[] = {
},
{
.name = "switcher-power-ok",
.handler = smblib_handle_debug,
.handler = smblib_handle_switcher_power_ok,
.storm_data = {true, 1000, 3},
},
};

View file

@ -596,7 +596,11 @@ static int smblib_usb_suspend_vote_callback(struct votable *votable, void *data,
{
struct smb_charger *chg = data;
return smblib_set_usb_suspend(chg, suspend);
/* resume input if suspend is invalid */
if (suspend < 0)
suspend = 0;
return smblib_set_usb_suspend(chg, (bool)suspend);
}
static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
@ -604,10 +608,11 @@ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
{
struct smb_charger *chg = data;
/* resume input if suspend is invalid */
if (suspend < 0)
suspend = false;
suspend = 0;
return smblib_set_dc_suspend(chg, suspend);
return smblib_set_dc_suspend(chg, (bool)suspend);
}
static int smblib_fcc_max_vote_callback(struct votable *votable, void *data,
@ -2230,11 +2235,8 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
}
}
if (!chg->dpdm_reg)
goto skip_dpdm_float;
if (chg->vbus_present) {
if (!regulator_is_enabled(chg->dpdm_reg)) {
if (chg->dpdm_reg && !regulator_is_enabled(chg->dpdm_reg)) {
smblib_dbg(chg, PR_MISC, "enabling DPDM regulator\n");
rc = regulator_enable(chg->dpdm_reg);
if (rc < 0)
@ -2242,7 +2244,14 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
rc);
}
} else {
if (regulator_is_enabled(chg->dpdm_reg)) {
if (chg->wa_flags & BOOST_BACK_WA) {
vote(chg->usb_suspend_votable,
BOOST_BACK_VOTER, false, 0);
vote(chg->dc_suspend_votable,
BOOST_BACK_VOTER, false, 0);
}
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)
@ -2251,7 +2260,6 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
}
}
skip_dpdm_float:
power_supply_changed(chg->usb_psy);
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s %s\n",
irq_data->name, chg->vbus_present ? "attached" : "detached");
@ -2683,6 +2691,39 @@ irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data)
return IRQ_HANDLED;
}
irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data)
{
struct smb_irq_data *irq_data = data;
struct smb_charger *chg = irq_data->parent_data;
int rc;
u8 stat;
if (!(chg->wa_flags & BOOST_BACK_WA))
return IRQ_HANDLED;
rc = smblib_read(chg, POWER_PATH_STATUS_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read POWER_PATH_STATUS rc=%d\n", rc);
return IRQ_HANDLED;
}
if ((stat & USE_USBIN_BIT) &&
get_effective_result(chg->usb_suspend_votable))
return IRQ_HANDLED;
if ((stat & USE_DCIN_BIT) &&
get_effective_result(chg->dc_suspend_votable))
return IRQ_HANDLED;
if (is_storming(&irq_data->storm_data)) {
smblib_dbg(chg, PR_MISC, "reverse boost detected; suspending input\n");
vote(chg->usb_suspend_votable, BOOST_BACK_VOTER, true, 0);
vote(chg->dc_suspend_votable, BOOST_BACK_VOTER, true, 0);
}
return IRQ_HANDLED;
}
/***************
* Work Queues *
***************/

View file

@ -46,6 +46,7 @@ enum print_reason {
#define VBUS_CC_SHORT_VOTER "VBUS_CC_SHORT_VOTER"
#define LEGACY_CABLE_VOTER "LEGACY_CABLE_VOTER"
#define PD_INACTIVE_VOTER "PD_INACTIVE_VOTER"
#define BOOST_BACK_VOTER "BOOST_BACK_VOTER"
enum smb_mode {
PARALLEL_MASTER = 0,
@ -55,6 +56,7 @@ enum smb_mode {
enum {
QC_CHARGER_DETECTION_WA_BIT = BIT(0),
BOOST_BACK_WA = BIT(1),
};
struct smb_regulator {
@ -240,6 +242,7 @@ irqreturn_t smblib_handle_icl_change(int irq, void *data);
irqreturn_t smblib_handle_usb_typec_change(int irq, void *data);
irqreturn_t smblib_handle_dc_plugin(int irq, void *data);
irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data);
irqreturn_t smblib_handle_switcher_power_ok(int irq, void *data);
int smblib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val);