mmi_parallel_charger: enhance the stability of sm work

Under certain condition, the PD adapter would be instability,
and the sm work who responsible for the entire charging policy
might exited abnormally.
improve the synchronous processing.

Change-Id: I87bb51a4b69178f9eb40d6519328975203027c7e
Signed-off-by: xuwt2 <xuwt2@lenovo.com>
Reviewed-on: https://gerrit.mot.com/1427554
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Jichao Zou <zoujc@motorola.com>
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1893556
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Reviewed-by: Wei Xu <xuwei9@lenovo.com>
This commit is contained in:
xuwt2 2019-09-25 11:37:34 +08:00 • committed by Wei Xu
commit c454984ac3
4 changed files with 100 additions and 30 deletions

View file

@ -629,7 +629,7 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr)
cancel_delayed_work(&chip->heartbeat_work);
schedule_delayed_work(&chip->heartbeat_work,
msecs_to_jiffies(0));
msecs_to_jiffies(1000));
}
@ -838,12 +838,13 @@ static DEVICE_ATTR(force_max_chrg_temp, 0644,
static void kick_sm(struct mmi_charger_manager *chip, int ms)
{
if (!delayed_work_pending(&chip->mmi_chrg_sm_work)) {
if (!chip->sm_work_running) {
mmi_chrg_dbg(chip, PR_INTERRUPT,
"lunch mmi chrg sm work\n");
"launch mmi chrg sm work\n");
mmi_chrg_policy_clear(chip);
schedule_delayed_work(&chip->mmi_chrg_sm_work,
msecs_to_jiffies(ms));
chip->sm_work_running = true;
} else
mmi_chrg_dbg(chip, PR_INTERRUPT,
"mmi chrg sm work already existed\n");
@ -851,9 +852,11 @@ static void kick_sm(struct mmi_charger_manager *chip, int ms)
static void cancel_sm(struct mmi_charger_manager *chip)
{
mmi_chrg_dbg(chip, PR_INTERRUPT, "flush and cancel mmi chrg sm work\n");
cancel_delayed_work_sync(&chip->mmi_chrg_sm_work);
flush_delayed_work(&chip->mmi_chrg_sm_work);
cancel_delayed_work(&chip->mmi_chrg_sm_work);
chip->sm_work_running = false;
mmi_chrg_dbg(chip, PR_INTERRUPT,
"cancel sync and flush mmi chrg sm work\n");
}
void clear_chg_manager(struct mmi_charger_manager *chip)
@ -968,10 +971,11 @@ static void mmi_heartbeat_work(struct work_struct *work)
{
struct mmi_charger_manager *chip = container_of(work,
struct mmi_charger_manager, heartbeat_work.work);
int hb_resch_time = 0, ret = 0;
int hb_resch_time = 0, ret = 0, i = 0;
char *chrg_rate_string = NULL;
char *envp[2];
union power_supply_propval val;
bool pd_active;
mmi_chrg_info(chip, "MMI: Heartbeat!\n");
/* Have not been resumed so wait another 100 ms */
@ -1006,7 +1010,6 @@ static void mmi_heartbeat_work(struct work_struct *work)
mmi_chrg_rate_check(chip);
hb_resch_time = HEARTBEAT_DELAY_MS;
if (chip->vbus_present)
alarm_start_relative(&chip->heartbeat_alarm,
ns_to_ktime(SMBCHG_HEARTBEAT_INTRVAL_NS));
@ -1034,9 +1037,66 @@ static void mmi_heartbeat_work(struct work_struct *work)
__pm_relax(&chip->mmi_hb_wake_source);
ret = power_supply_get_property(chip->usb_psy,
POWER_SUPPLY_PROP_PD_ACTIVE, &val);
if (ret) {
mmi_chrg_err(chip, "Unable to read PD ACTIVE: %d\n", ret);
goto schedule_work;
}
pd_active = val.intval;
if (!chip->pd_handle) {
chip->pd_handle = devm_usbpd_get_by_phandle(chip->dev,
"qcom,usbpd-phandle");
if (IS_ERR_OR_NULL(chip->pd_handle)) {
mmi_chrg_err(chip, "Error getting the pd phandle %ld\n",
PTR_ERR(chip->pd_handle));
chip->pd_handle = NULL;
goto schedule_work;
}
}
if (!chip->sm_work_running && chip->vbus_present
&& pd_active) {
usbpd_get_pdo_info(chip->pd_handle, chip->mmi_pdo_info);
mmi_chrg_info(chip, "check all effective pdo info\n");
for (i = 0; i < PD_MAX_PDO_NUM; i++) {
if ((chip->mmi_pdo_info[i].type ==
PD_SRC_PDO_TYPE_AUGMENTED)
&& chip->mmi_pdo_info[i].uv_max >= PUMP_CHARGER_PPS_MIN_VOLT
&& chip->mmi_pdo_info[i].ua >= TYPEC_MIDDLE_CURRENT_UA) {
chip->mmi_pd_pdo_idx = chip->mmi_pdo_info[i].pdo_pos;
mmi_chrg_info(chip,
"pd charger support pps, pdo %d, "
"volt %d, curr %d \n",
chip->mmi_pd_pdo_idx,
chip->mmi_pdo_info[i].uv_max,
chip->mmi_pdo_info[i].ua);
chip->pd_pps_support = true;
if (chip->mmi_pdo_info[i].uv_max <
chip->pd_volt_max) {
chip->pd_volt_max =
chip->mmi_pdo_info[i].uv_max;
}
if (chip->mmi_pdo_info[i].ua <
chip->pd_curr_max) {
chip->pd_curr_max =
chip->mmi_pdo_info[i].ua;
}
break;
}
}
if (chip->pd_pps_support) {
mmi_chrg_info(chip, "MMI: Heartbeat!, launch sm work\n");
kick_sm(chip, 100);
}
}
schedule_work:
schedule_delayed_work(&chip->heartbeat_work,
msecs_to_jiffies(hb_resch_time));
}
static void psy_changed_work_func(struct work_struct *work)

View file

@ -200,7 +200,7 @@ struct mmi_charger_manager {
struct delayed_work heartbeat_work; /*cycle trig heartbeat work*/
struct completion sm_completion;
struct work_struct psy_changed_work; /*the change notification of power supply*/
bool sm_work_running;
int num_temp_zones;
struct mmi_chrg_temp_zone *temp_zones; /*the temperature zone of charging*/
enum mmi_chrg_temp_zones pres_temp_zone; /*the present zone idx*/

View file

@ -30,4 +30,5 @@
extern int mmi_chrg_policy_init(struct mmi_charger_manager *chip,
struct mmi_chrg_dts_info *chrg_dts,
int chrg_cnt);
extern void mmi_chrg_policy_clear(struct mmi_charger_manager *chip);
#endif

View file

@ -171,6 +171,7 @@ static void clear_chrg_dev_error_cnt(struct mmi_charger_manager *chip, struct mm
for (i = 0; i < chrg_num; i++) {
if (is_charger_exist(dev_ops[i].dev_name)) {
chrg_dev = chrg_list->chrg_dev[i];
chrg_dev->charger_error.chrg_err_type = 0;
chrg_dev->charger_error.bus_ucp_err_cnt = 0;
chrg_dev->charger_error.bus_ocp_err_cnt = 0;
}
@ -285,6 +286,20 @@ static void chrg_policy_error_recovery(struct mmi_charger_manager *chip,
#define PPS_SELECT_PDO_RETRY_COUNT 3
#define DISABLE_CHRG_LIMIT -1
#define CP_CHRG_SOC_LIMIT 90
void mmi_chrg_policy_clear(struct mmi_charger_manager *chip) {
chrg_dev_init(chip, &g_chrg_list);
clear_chrg_dev_error_cnt(chip, &g_chrg_list);;
clear_chg_manager(chip);
sm_state = PM_STATE_DISCONNECT;
chip->pps_volt_comp = PPS_INIT_VOLT_COMP;
quit_slave_chrg_cnt = 0;
chrg_cc_power_tunning_cnt = 0;
chrg_cv_taper_tunning_cnt = 0;
chrg_cv_delta_volt = 0;
return;
}
static void mmi_chrg_sm_work_func(struct work_struct *work)
{
struct mmi_charger_manager *chip = container_of(work,
@ -405,6 +420,12 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
"Enter into COOLING LOOP !\n",
batt_temp, chrg_step->temp_c);
chip->thermal_cooling = true;
} else {
mmi_chrg_info(chip, "battery temp %d, temp thre %d "
"Restart select chrg step and temp zone !\n",
batt_temp, chrg_step->temp_c);
mmi_find_chrg_step(chip, chip->pres_temp_zone, vbatt_volt);
mmi_chrg_sm_move_state(chip, PM_STATE_ENTRY);
}
}
@ -659,17 +680,16 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
}
break;
case PM_STATE_PPS_TUNNING_CURR:
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
if (chrg_list->cp_master
&& !chrg_list->chrg_dev[CP_MASTER]->charger_enabled) {
mmi_chrg_info(chip,"CP MASTER was disabled, Enter into "
"SW directly\n");
mmi_chrg_sm_move_state(chip, PM_STATE_SW_ENTRY);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
}else if (vbatt_volt > chrg_step->chrg_step_cv_volt) {
chip->pd_request_curr -= chip->pps_curr_steps;
mmi_chrg_sm_move_state(chip,
PM_STATE_CP_CC_LOOP);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
mmi_chrg_info(chip,"Duing the curr going up process, "
"the chrg step was changed,"
"stop increase pps curr and Enter into "
@ -678,7 +698,6 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
if (mmi_get_pps_result_history(chip) != NO_ERROR) {
mmi_chrg_sm_move_state(chip,
PM_STATE_CP_CC_LOOP);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
mmi_chrg_info(chip,"Too many pdo request failed,"
" Enter into CC stage directly!\n");
}
@ -695,10 +714,10 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
} else {
mmi_chrg_info(chip,"Enter into tunning pps volt\n");
mmi_chrg_sm_move_state(chip, PM_STATE_PPS_TUNNING_VOLT);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
}
break;
case PM_STATE_PPS_TUNNING_VOLT:
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
if (chrg_list->cp_slave
&& chrg_list->cp_clave_later
&& !chrg_list->chrg_dev[CP_SLAVE]->charger_enabled) {
@ -711,12 +730,10 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
mmi_chrg_info(chip,"CP MASTER was disabled, "
"Enter into SW directly\n");
mmi_chrg_sm_move_state(chip, PM_STATE_SW_ENTRY);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
} else if (vbatt_volt > chrg_step->chrg_step_cv_volt) {
chip->pd_request_volt -= chip->pps_volt_steps;
mmi_chrg_sm_move_state(chip,
PM_STATE_CP_CC_LOOP);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
mmi_chrg_info(chip,"Duing the volt going up process, "
"the chrg step was changed,"
"stop increase pps volt and"
@ -725,7 +742,6 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
if (mmi_get_pps_result_history(chip) != NO_ERROR) {
mmi_chrg_sm_move_state(chip,
PM_STATE_CP_CC_LOOP);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
mmi_chrg_info(chip,"Too many pdo request failed,"
" Enter into CC stage directly!\n");
}
@ -744,7 +760,6 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
} else {
mmi_chrg_info(chip,"Enter into CC loop stage !\n");
mmi_chrg_sm_move_state(chip, PM_STATE_CP_CC_LOOP);
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
}
break;
case PM_STATE_CP_CC_LOOP:
@ -791,7 +806,6 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
goto schedule;
}
if (!chip->thermal_cooling
&& !chip->thermal_mitigation_doing) {
if (ibatt_curr < chrg_step->chrg_step_cc_curr
@ -1031,6 +1045,7 @@ static void mmi_chrg_sm_work_func(struct work_struct *work)
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
break;
case PM_STATE_RECOVERY_SW:
heartbeat_dely_ms = HEARTBEAT_SHORT_DELAY_MS;
if (chrg_list->chrg_dev[PMIC_SW]->charger_limited) {
mmi_set_charing_current(chrg_list->chrg_dev[PMIC_SW],
chrg_list->chrg_dev[PMIC_SW]->input_curr_setted);
@ -1357,21 +1372,15 @@ schedule:
chip->pd_request_curr_prev = chip->pd_target_curr;
}
if (heartbeat_dely_ms >= 0) {
if (heartbeat_dely_ms > 0) {
if (chip->pps_result < 0)
heartbeat_dely_ms = 0;
heartbeat_dely_ms = HEARTBEAT_NEXT_STATE_MS;
mmi_chrg_err(chip, "schedule work timer %d\n", heartbeat_dely_ms);
schedule_delayed_work(&chip->mmi_chrg_sm_work,
msecs_to_jiffies(heartbeat_dely_ms));
} else {
chrg_dev_init(chip, &g_chrg_list);
clear_chrg_dev_error_cnt(chip, &g_chrg_list);
clear_chg_manager(chip);
sm_state = PM_STATE_DISCONNECT;
chip->pps_volt_comp = PPS_INIT_VOLT_COMP;
quit_slave_chrg_cnt = 0;
chrg_cc_power_tunning_cnt = 0;
chrg_cv_taper_tunning_cnt = 0;
chrg_cv_delta_volt = 0;
mmi_chrg_policy_clear(chip);
chip->sm_work_running = false;
mmi_chrg_err(chip, "exit sm work\n");
}