diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h index b75d7db57c3e..1935704fcf09 100644 --- a/drivers/power/supply/qcom/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h @@ -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; diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 256d9ed8ada5..e5f8ef5bdea3 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -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; }