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

Commit fa88f5e4 authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: qpnp-fg-gen3: Skip the status_change work if suspended



There is a scenario where the status change work can hold
a mutex lock for ~1.5 seconds which can race with the FG resume
callback. Avoid this condition by adding a state variable
to track the suspend/resume state and skip executing the
status change work while suspended.

CRs-Fixed: 2101514
Change-Id: Ib5300a5dfce30c4c6bcc8d8428b664c184a83fb4
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 11734d04
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -404,6 +404,7 @@ struct fg_chip {
	struct mutex		sram_rw_lock;
	struct mutex		charge_full_lock;
	struct mutex		qnovo_esr_ctrl_lock;
	spinlock_t		suspend_lock;
	u32			batt_soc_base;
	u32			batt_info_base;
	u32			mem_if_base;
@@ -438,6 +439,7 @@ struct fg_chip {
	bool			slope_limit_en;
	bool			use_ima_single_mode;
	bool			qnovo_enable;
	bool			suspended;
	struct completion	soc_update;
	struct completion	soc_ready;
	struct delayed_work	profile_load_work;
+23 −0
Original line number Diff line number Diff line
@@ -3776,6 +3776,14 @@ static int fg_notifier_cb(struct notifier_block *nb,
	struct power_supply *psy = data;
	struct fg_chip *chip = container_of(nb, struct fg_chip, nb);

	spin_lock(&chip->suspend_lock);
	if (chip->suspended) {
		/* Return if we are still suspended */
		spin_unlock(&chip->suspend_lock);
		return NOTIFY_OK;
	}
	spin_unlock(&chip->suspend_lock);

	if (event != PSY_EVENT_PROP_CHANGED)
		return NOTIFY_OK;

@@ -5089,6 +5097,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
	mutex_init(&chip->ttf.lock);
	mutex_init(&chip->charge_full_lock);
	mutex_init(&chip->qnovo_esr_ctrl_lock);
	spin_lock_init(&chip->suspend_lock);
	init_completion(&chip->soc_update);
	init_completion(&chip->soc_ready);
	INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
@@ -5186,6 +5195,10 @@ static int fg_gen3_suspend(struct device *dev)
	struct fg_chip *chip = dev_get_drvdata(dev);
	int rc;

	spin_lock(&chip->suspend_lock);
	chip->suspended = true;
	spin_unlock(&chip->suspend_lock);

	rc = fg_esr_timer_config(chip, true);
	if (rc < 0)
		pr_err("Error in configuring ESR timer, rc=%d\n", rc);
@@ -5209,6 +5222,16 @@ static int fg_gen3_resume(struct device *dev)
	if (fg_sram_dump)
		schedule_delayed_work(&chip->sram_dump_work,
				msecs_to_jiffies(fg_sram_dump_period_ms));

	if (!work_pending(&chip->status_change_work)) {
		pm_stay_awake(chip->dev);
		schedule_work(&chip->status_change_work);
	}

	spin_lock(&chip->suspend_lock);
	chip->suspended = false;
	spin_unlock(&chip->suspend_lock);

	return 0;
}