From 809a55ee88cfc67b105ec161f7f211ef2e26ca3a Mon Sep 17 00:00:00 2001 From: Yonghua Yan Date: Fri, 17 May 2019 17:50:07 +0800 Subject: [PATCH] power: battery wakelock prevents system suspending This issue is due to the race between power_supply_changed() and smb_mmi_power_supply_changed(). First, power_supply_changed() holds the battery wakelock and releases the wakelock if battery supply change work is scheduled. And then, qpnp-smbcharger-mmi driver set the supply changed flag to be true, call smb_mmi_power_supply_changed() and wait for battery supply change work completion, where it does not release the wakelock as the supply changed flag becomes true. Finally, the battery wakelock will not be released any more. Change-Id: I57f4728cb6510acce004d5d84489695035c10eaf Signed-off-by: Yonghua Yan Reviewed-on: https://gerrit.mot.com/1357520 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Kenneth Kessler Submit-Approved: Jira Key --- .../qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c b/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c index 02370070101d..4b3b53763672 100644 --- a/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c +++ b/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c @@ -2500,30 +2500,13 @@ static int __smb_mmi_ps_changed(struct device *dev, void *data) static void smb_mmi_power_supply_changed(struct power_supply *psy, char *envp_ext[]) { - unsigned long flags; - dev_err(&psy->dev, "%s: %s\n", __func__, envp_ext[0]); - spin_lock_irqsave(&psy->changed_lock, flags); - /* - * Check 'changed' here to avoid issues due to race between - * power_supply_changed() and this routine. In worst case - * power_supply_changed() can be called again just before we take above - * lock. During the first call of this routine we will mark 'changed' as - * false and it will stay false for the next call as well. - */ - if (likely(psy->changed)) { - psy->changed = false; - spin_unlock_irqrestore(&psy->changed_lock, flags); - class_for_each_device(power_supply_class, NULL, psy, - __smb_mmi_ps_changed); - atomic_notifier_call_chain(&power_supply_notifier, - PSY_EVENT_PROP_CHANGED, psy); - kobject_uevent_env(&psy->dev.kobj, KOBJ_CHANGE, envp_ext); - spin_lock_irqsave(&psy->changed_lock, flags); - } - - spin_unlock_irqrestore(&psy->changed_lock, flags); + class_for_each_device(power_supply_class, NULL, psy, + __smb_mmi_ps_changed); + atomic_notifier_call_chain(&power_supply_notifier, + PSY_EVENT_PROP_CHANGED, psy); + kobject_uevent_env(&psy->dev.kobj, KOBJ_CHANGE, envp_ext); } static int factory_kill_disable; @@ -2916,10 +2899,8 @@ sch_hb: } if (chip->batt_psy) { - chip->batt_psy->changed = true; smb_mmi_power_supply_changed(chip->batt_psy, envp); } else if (chip->qcom_psy) { - chip->qcom_psy->changed = true; smb_mmi_power_supply_changed(chip->qcom_psy, envp); }