qcom-charger: Fix a possible null ptr access of pl psy

The issue results from a earlier wrong assumption that parallel
psy is available when master side is ready. The happens on boot
with a strong charger attached, when FCC callback is about to
redistribute charging currents while parallel charger has not
yet probed, hence pl psy is invalid when accessed.

This issue is fixed by introducing parallel charger as a parallel
charging voter, which is also convenient for debugging purpose.

CRs-Fixed: 1059499
Change-Id: Ic96d30a02c966704d98e047602e4292f576fe448
Signed-off-by: Harry Yang <harryy@codeaurora.org>
This commit is contained in:
Harry Yang 2016-08-29 16:06:50 -07:00 committed by Nicholas Troast
parent 166e851cfd
commit 81aa304c8d
3 changed files with 22 additions and 17 deletions

View file

@ -986,6 +986,8 @@ static int smb2_init_hw(struct smb2 *chip)
USBIN_ICL_VOTER, true, 0);
vote(chg->pl_disable_votable,
CHG_STATE_VOTER, true, 0);
vote(chg->pl_disable_votable,
PARALLEL_PSY_VOTER, true, 0);
vote(chg->usb_suspend_votable,
DEFAULT_VOTER, chip->dt.no_battery, 0);
vote(chg->dc_suspend_votable,

View file

@ -2178,8 +2178,7 @@ static void smblib_pl_detect_work(struct work_struct *work)
struct smb_charger *chg = container_of(work, struct smb_charger,
pl_detect_work);
if (!get_effective_result_locked(chg->pl_disable_votable))
rerun_election(chg->pl_disable_votable);
vote(chg->pl_disable_votable, PARALLEL_PSY_VOTER, false, 0);
}
#define MINIMUM_PARALLEL_FCC_UA 500000
@ -2204,7 +2203,7 @@ static void smblib_pl_taper_work(struct work_struct *work)
}
if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) {
vote(chg->awake_votable, PL_VOTER, true, 0);
vote(chg->awake_votable, PL_TAPER_WORK_RUNNING_VOTER, true, 0);
/* Reduce the taper percent by 25 percent */
chg->pl.taper_percent = chg->pl.taper_percent
* TAPER_RESIDUAL_PERCENT / 100;
@ -2218,7 +2217,7 @@ static void smblib_pl_taper_work(struct work_struct *work)
* Master back to Fast Charge, get out of this round of taper reduction
*/
done:
vote(chg->awake_votable, PL_VOTER, false, 0);
vote(chg->awake_votable, PL_TAPER_WORK_RUNNING_VOTER, false, 0);
}
static void clear_hdc_work(struct work_struct *work)
@ -2381,9 +2380,6 @@ int smblib_init(struct smb_charger *chg)
return rc;
}
chg->bms_psy = power_supply_get_by_name("bms");
chg->pl.psy = power_supply_get_by_name("parallel");
rc = smblib_register_notifier(chg);
if (rc < 0) {
dev_err(chg->dev,
@ -2391,6 +2387,12 @@ int smblib_init(struct smb_charger *chg)
return rc;
}
chg->bms_psy = power_supply_get_by_name("bms");
chg->pl.psy = power_supply_get_by_name("parallel");
if (chg->pl.psy)
vote(chg->pl_disable_votable, PARALLEL_PSY_VOTER,
false, 0);
break;
case PARALLEL_SLAVE:
break;

View file

@ -24,16 +24,17 @@ enum print_reason {
PR_MISC = BIT(2),
};
#define DEFAULT_VOTER "DEFAULT_VOTER"
#define USER_VOTER "USER_VOTER"
#define PD_VOTER "PD_VOTER"
#define PL_VOTER "PL_VOTER"
#define USBIN_ICL_VOTER "USBIN_ICL_VOTER"
#define CHG_STATE_VOTER "CHG_STATE_VOTER"
#define TYPEC_SRC_VOTER "TYPEC_SRC_VOTER"
#define TAPER_END_VOTER "TAPER_END_VOTER"
#define FCC_MAX_RESULT "FCC_MAX_RESULT"
#define THERMAL_DAEMON "THERMAL_DAEMON"
#define DEFAULT_VOTER "DEFAULT_VOTER"
#define USER_VOTER "USER_VOTER"
#define PD_VOTER "PD_VOTER"
#define PL_TAPER_WORK_RUNNING_VOTER "PL_TAPER_WORK_RUNNING_VOTER"
#define PARALLEL_PSY_VOTER "PARALLEL_PSY_VOTER"
#define USBIN_ICL_VOTER "USBIN_ICL_VOTER"
#define CHG_STATE_VOTER "CHG_STATE_VOTER"
#define TYPEC_SRC_VOTER "TYPEC_SRC_VOTER"
#define TAPER_END_VOTER "TAPER_END_VOTER"
#define FCC_MAX_RESULT "FCC_MAX_RESULT"
#define THERMAL_DAEMON "THERMAL_DAEMON"
enum smb_mode {
PARALLEL_MASTER = 0,