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

Commit 65788317 authored by Anirudh Ghayal's avatar Anirudh Ghayal Committed by Subbaraman Narayanamurthy
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 9d4600a1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -434,6 +434,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;
@@ -470,6 +471,7 @@ struct fg_chip {
	bool			use_ima_single_mode;
	bool			use_dma;
	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
@@ -3891,6 +3891,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;

@@ -5285,6 +5293,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);
@@ -5383,6 +5392,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);
@@ -5406,6 +5419,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;
}