From aed5336114a5c1fdf52d1fb7a01455f097a975aa Mon Sep 17 00:00:00 2001 From: Kenny Kessler Date: Thu, 16 May 2019 08:31:18 -0500 Subject: [PATCH] power: qpnp-smbcharger-mmi: Add Suspend SOC Recalc When the System Suspends the running last reported SOC needs to be reset. The reason is that the SOC could have moved a large amount while sleeping. The curretn SOC needs to be recalculated so that the changes is noticable to the User upon wakeup. To do this keep track of the Suspend state as well as the fact that the heartbeat has not run yet after a Suspend. The WAS_SUSPEND bit will track this and then be cleared once the heartbeat gets past the point that the information is not longer needed. For Dual Batteries, this will force the last_reported_soc to be updated with the current calculation rather then trying to Monotonically adjust it slowly. Change-Id: I0de830df74720f0f26f8f7a7cfcba7698f6a6dd6 Signed-off-by: Kenny Kessler Reviewed-on: https://gerrit.mot.com/1355819 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Curtis Porter Reviewed-by: Kenneth Kessler Submit-Approved: Jira Key --- .../qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c b/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c index d59b0d5afca8..fff92d8417f2 100644 --- a/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c +++ b/drivers/power/qpnp-smbcharger-mmi/qpnp-smbcharger-mmi.c @@ -223,6 +223,9 @@ enum charging_limit_modes { CHARGING_LIMIT_UNKNOWN, }; +#define IS_SUSPENDED BIT(0) +#define WAS_SUSPENDED BIT(1) + struct smb_mmi_charger { struct device *dev; struct regmap *regmap; @@ -271,7 +274,7 @@ struct smb_mmi_charger { int vfloat_comp_mv; struct wakeup_source smb_mmi_hb_wake_source; struct alarm heartbeat_alarm; - bool suspended; + int suspended; bool awake; int last_reported_soc; int last_reported_status; @@ -2430,7 +2433,7 @@ static void mmi_heartbeat_work(struct work_struct *work) struct smb_mmi_chg_status chg_stat; /* Have not been resumed so wait another 100 ms */ - if (chip->suspended) { + if (chip->suspended & IS_SUSPENDED) { pr_err("SMBMMI: HB running before Resume\n"); schedule_delayed_work(&chip->heartbeat_work, msecs_to_jiffies(100)); @@ -2582,7 +2585,10 @@ static void mmi_heartbeat_work(struct work_struct *work) else if (report_cap > 100) report_cap = 100; - batt_cap = chip->last_reported_soc; + if (chip->suspended & WAS_SUSPENDED) + batt_cap = -1; + else + batt_cap = chip->last_reported_soc; if ((batt_cap == -1) || ((report_cap != batt_cap) && @@ -2718,6 +2724,7 @@ static void mmi_heartbeat_work(struct work_struct *work) } } prev_vbus_mv = chg_stat.usb_mv; + chip->suspended = 0; if (chip->factory_mode || (chip->is_factory_image && chip->enable_factory_poweroff)) { @@ -3331,7 +3338,7 @@ static int smb_mmi_probe(struct platform_device *pdev) chip->dev = &pdev->dev; psy_cfg.drv_data = chip; platform_set_drvdata(pdev, chip); - chip->suspended = false; + chip->suspended = 0; chip->awake = false; device_init_wakeup(chip->dev, true); @@ -3664,7 +3671,8 @@ static int smb_mmi_suspend(struct device *device) struct platform_device *pdev = to_platform_device(device); struct smb_mmi_charger *chip = platform_get_drvdata(pdev); - chip->suspended = true; + chip->suspended &= ~WAS_SUSPENDED; + chip->suspended |= IS_SUSPENDED; return 0; } @@ -3674,7 +3682,8 @@ static int smb_mmi_resume(struct device *device) struct platform_device *pdev = to_platform_device(device); struct smb_mmi_charger *chip = platform_get_drvdata(pdev); - chip->suspended = false; + chip->suspended &= ~IS_SUSPENDED; + chip->suspended |= WAS_SUSPENDED; return 0; }