Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49f18a6b authored by Ashay Jaiswal's avatar Ashay Jaiswal Committed by Anirudh Ghayal
Browse files

qpnp-fg: fix integer overflow



There is a possibility of integer overflow during capacity
learning calculation. Fix this by storing intermediate results
in 64 bit variable.

CRs-Fixed: 2070510
Change-Id: I70b6ef0796be010129f8d8a7380f685bb76daf7d
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent 38afda62
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -3559,6 +3559,7 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip)
	int cc_pc_val, rc = -EINVAL;
	unsigned int cc_soc_delta_pc;
	int64_t delta_cc_uah;
	uint64_t temp;
	bool batt_missing = is_battery_missing(chip);

	if (batt_missing) {
@@ -3581,9 +3582,8 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip)
		goto fail;
	}

	cc_soc_delta_pc = DIV_ROUND_CLOSEST(
			abs(cc_pc_val - chip->learning_data.init_cc_pc_val)
			* 100, FULL_PERCENT_28BIT);
	temp = abs(cc_pc_val - chip->learning_data.init_cc_pc_val);
	cc_soc_delta_pc = DIV_ROUND_CLOSEST_ULL(temp * 100, FULL_PERCENT_28BIT);

	delta_cc_uah = div64_s64(
			chip->learning_data.learned_cc_uah * cc_soc_delta_pc,
@@ -3591,8 +3591,11 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip)
	chip->learning_data.cc_uah = delta_cc_uah + chip->learning_data.cc_uah;

	if (fg_debug_mask & FG_AGING)
		pr_info("current cc_soc=%d cc_soc_pc=%d total_cc_uah = %lld\n",
		pr_info("current cc_soc=%d cc_soc_pc=%d init_cc_pc_val=%d delta_cc_uah=%lld learned_cc_uah=%lld total_cc_uah = %lld\n",
				cc_pc_val, cc_soc_delta_pc,
				chip->learning_data.init_cc_pc_val,
				delta_cc_uah,
				chip->learning_data.learned_cc_uah,
				chip->learning_data.cc_uah);

	return 0;
@@ -4147,10 +4150,10 @@ static void status_change_work(struct work_struct *work)

	if ((chip->wa_flag & USE_CC_SOC_REG) && chip->bad_batt_detection_en
			&& chip->safety_timer_expired) {
		chip->sw_cc_soc_data.delta_soc =
			DIV_ROUND_CLOSEST(abs(cc_soc -
					chip->sw_cc_soc_data.init_cc_soc)
					* 100, FULL_PERCENT_28BIT);
		uint64_t delta_cc_soc = abs(cc_soc -
					chip->sw_cc_soc_data.init_cc_soc);
		chip->sw_cc_soc_data.delta_soc = DIV_ROUND_CLOSEST_ULL(
				delta_cc_soc * 100, FULL_PERCENT_28BIT);
		chip->sw_cc_soc_data.full_capacity =
			chip->sw_cc_soc_data.delta_soc +
			chip->sw_cc_soc_data.init_sys_soc;