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

Commit 40dc2a33 authored by Anirudh Ghayal's avatar Anirudh Ghayal Committed by Shilpa Suresh
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 762a4bac
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -438,6 +438,7 @@ struct fg_dev {
	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;
@@ -467,6 +468,7 @@ struct fg_dev {
	bool			use_dma;
	bool			qnovo_enable;
	enum fg_version		version;
	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
@@ -3489,6 +3489,14 @@ static int fg_notifier_cb(struct notifier_block *nb,
	struct power_supply *psy = data;
	struct fg_dev *fg = container_of(nb, struct fg_dev, nb);

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

	if (event != PSY_EVENT_PROP_CHANGED)
		return NOTIFY_OK;

@@ -4789,6 +4797,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
	mutex_init(&chip->cl.lock);
	mutex_init(&chip->ttf.lock);
	mutex_init(&fg->qnovo_esr_ctrl_lock);
	spin_lock_init(&fg->suspend_lock);
	init_completion(&fg->soc_update);
	init_completion(&fg->soc_ready);
	INIT_DELAYED_WORK(&fg->profile_load_work, profile_load_work);
@@ -4888,6 +4897,10 @@ static int fg_gen3_suspend(struct device *dev)
	struct fg_dev *fg = &chip->fg;
	int rc;

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

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

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

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

	return 0;
}