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

Commit e849bd31 authored by Xiaozhe Shi's avatar Xiaozhe Shi
Browse files

power: qpnp-fg: wait for the battery psy when loading profile



Currently the fuel gauge driver needs the charger to stop charging while
doing a profile reload. However, it is not guaranteed that the fuel
gauge driver probes after the charger driver probes and registers the
battery power supply. This can cause an issue where the battery is still
being charged when doing a profile reload, creating issues with the fuel
gauge SOC upon a cold boot.

Fix this by waiting for the battery power supply to load before loading
a profile.

Change-Id: I23ce2bc0f70390ac41d7a2130b33428c18d8ddba
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent aee40d4f
Loading
Loading
Loading
Loading
+22 −7
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ struct fg_chip {
	struct power_supply	bms_psy;
	struct mutex		rw_lock;
	struct mutex		sysfs_restart_lock;
	struct work_struct	batt_profile_init;
	struct delayed_work	batt_profile_init;
	struct work_struct	dump_sram;
	struct work_struct	status_change_work;
	struct work_struct	cycle_count_work;
@@ -3764,7 +3764,7 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *_chip)
		if (!chip->use_otp_profile) {
			reinit_completion(&chip->batt_id_avail);
			reinit_completion(&chip->first_soc_done);
			schedule_work(&chip->batt_profile_init);
			schedule_delayed_work(&chip->batt_profile_init, 0);
			cancel_delayed_work(&chip->update_sram_data);
			schedule_delayed_work(
				&chip->update_sram_data,
@@ -4426,6 +4426,7 @@ fail:
#define PROFILE_COMPARE_LEN		32
#define THERMAL_COEFF_ADDR		0x444
#define THERMAL_COEFF_OFFSET		0x2
#define BATTERY_PSY_WAIT_MS		2000
static int fg_batt_profile_init(struct fg_chip *chip)
{
	int rc = 0, ret;
@@ -4593,6 +4594,14 @@ wait:
				DUMP_PREFIX_NONE, 16, 1,
				chip->batt_profile, len, false);
	}
	if (!chip->batt_psy && chip->batt_psy_name)
		chip->batt_psy = power_supply_get_by_name(chip->batt_psy_name);

	if (!chip->batt_psy) {
		if (fg_debug_mask & FG_STATUS)
			pr_info("batt psy not registered\n");
		goto reschedule;
	}
	if (chip->power_supply_registered)
		power_supply_changed(&chip->bms_psy);

@@ -4659,6 +4668,12 @@ no_profile:
		power_supply_changed(&chip->bms_psy);
	fg_relax(&chip->profile_wakeup_source);
	return rc;
reschedule:
	schedule_delayed_work(
		&chip->batt_profile_init,
		msecs_to_jiffies(BATTERY_PSY_WAIT_MS));
	fg_relax(&chip->profile_wakeup_source);
	return 0;
}

static void check_empty_work(struct work_struct *work)
@@ -4681,7 +4696,7 @@ static void batt_profile_init(struct work_struct *work)
{
	struct fg_chip *chip = container_of(work,
				struct fg_chip,
				batt_profile_init);
				batt_profile_init.work);

	if (fg_batt_profile_init(chip))
		pr_err("failed to initialize profile\n");
@@ -5204,11 +5219,11 @@ static void fg_cleanup(struct fg_chip *chip)
	cancel_delayed_work_sync(&chip->update_temp_work);
	cancel_delayed_work_sync(&chip->update_jeita_setting);
	cancel_delayed_work_sync(&chip->check_empty_work);
	cancel_delayed_work_sync(&chip->batt_profile_init);
	alarm_try_to_cancel(&chip->fg_cap_learning_alarm);
	cancel_work_sync(&chip->rslow_comp_work);
	cancel_work_sync(&chip->set_resume_soc_work);
	cancel_work_sync(&chip->fg_cap_learning_work);
	cancel_work_sync(&chip->batt_profile_init);
	cancel_work_sync(&chip->dump_sram);
	cancel_work_sync(&chip->status_change_work);
	cancel_work_sync(&chip->cycle_count_work);
@@ -6016,7 +6031,7 @@ static void delayed_init_work(struct work_struct *work)
		update_temp_data(&chip->update_temp_work.work);

	if (!chip->use_otp_profile)
		schedule_work(&chip->batt_profile_init);
		schedule_delayed_work(&chip->batt_profile_init, 0);

	if (chip->wa_flag & IADC_GAIN_COMP_WA) {
		/* read default gain config */
@@ -6129,9 +6144,9 @@ static int fg_probe(struct spmi_device *spmi)
	INIT_DELAYED_WORK(&chip->update_sram_data, update_sram_data_work);
	INIT_DELAYED_WORK(&chip->update_temp_work, update_temp_data);
	INIT_DELAYED_WORK(&chip->check_empty_work, check_empty_work);
	INIT_DELAYED_WORK(&chip->batt_profile_init, batt_profile_init);
	INIT_WORK(&chip->rslow_comp_work, rslow_comp_work);
	INIT_WORK(&chip->fg_cap_learning_work, fg_cap_learning_work);
	INIT_WORK(&chip->batt_profile_init, batt_profile_init);
	INIT_WORK(&chip->dump_sram, dump_sram);
	INIT_WORK(&chip->status_change_work, status_change_work);
	INIT_WORK(&chip->cycle_count_work, update_cycle_count);
@@ -6292,10 +6307,10 @@ cancel_work:
	cancel_delayed_work_sync(&chip->update_sram_data);
	cancel_delayed_work_sync(&chip->update_temp_work);
	cancel_delayed_work_sync(&chip->check_empty_work);
	cancel_delayed_work_sync(&chip->batt_profile_init);
	alarm_try_to_cancel(&chip->fg_cap_learning_alarm);
	cancel_work_sync(&chip->set_resume_soc_work);
	cancel_work_sync(&chip->fg_cap_learning_work);
	cancel_work_sync(&chip->batt_profile_init);
	cancel_work_sync(&chip->dump_sram);
	cancel_work_sync(&chip->status_change_work);
	cancel_work_sync(&chip->cycle_count_work);