diff --git a/drivers/power/mmi_parallel_charger/mmi_charger_core.c b/drivers/power/mmi_parallel_charger/mmi_charger_core.c index 3c6017b15c34..71b9fd2904ef 100644 --- a/drivers/power/mmi_parallel_charger/mmi_charger_core.c +++ b/drivers/power/mmi_parallel_charger/mmi_charger_core.c @@ -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) diff --git a/drivers/power/mmi_parallel_charger/mmi_charger_core.h b/drivers/power/mmi_parallel_charger/mmi_charger_core.h index 6cd51f01292a..b0933e3ac2be 100644 --- a/drivers/power/mmi_parallel_charger/mmi_charger_core.h +++ b/drivers/power/mmi_parallel_charger/mmi_charger_core.h @@ -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*/ diff --git a/drivers/power/mmi_parallel_charger/mmi_charger_policy.h b/drivers/power/mmi_parallel_charger/mmi_charger_policy.h index 41426a86e60a..b24392e75166 100644 --- a/drivers/power/mmi_parallel_charger/mmi_charger_policy.h +++ b/drivers/power/mmi_parallel_charger/mmi_charger_policy.h @@ -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 diff --git a/drivers/power/mmi_parallel_charger/mmi_charger_pump_policy.c b/drivers/power/mmi_parallel_charger/mmi_charger_pump_policy.c index 07ad01706b94..e5cc2975730e 100644 --- a/drivers/power/mmi_parallel_charger/mmi_charger_pump_policy.c +++ b/drivers/power/mmi_parallel_charger/mmi_charger_pump_policy.c @@ -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"); }