From 6c03f79a1f550065cc27ac6afed1e27e103d3935 Mon Sep 17 00:00:00 2001
From: l00228880 <l00228880@notesmail.huawei.com>
Date: Fri, 23 Jun 2017 15:37:18 +0800
Subject: [PATCH] power: charger: fix a bug about charging icon which dose not
 disappear when charger is gone

When battery is full, it will set a flag to represent this event. The flag is cleared
in charger gone interrupt process. However, when charger is gone, the gone interrupt
has not happen after a long time low probability. This may be a hardware error.
So when the bug happens, fix it in charging status interface and usb online interface.

Change-Id: I3c00276ce361b967a1df8cfaba0c46b9566b8e0f
---
 drivers/power/mp2661-charger.c | 43 ++++++++++++++++++++++++----------
 drivers/usb/phy/phy-msm-usb.c  | 15 ++++--------
 2 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/power/mp2661-charger.c b/drivers/power/mp2661-charger.c
index 6dee66fce025..13fe7137865a 100644
--- a/drivers/power/mp2661-charger.c
+++ b/drivers/power/mp2661-charger.c
@@ -410,9 +410,10 @@ static enum power_supply_property mp2661_battery_properties[] = {
     POWER_SUPPLY_PROP_NOTIFY_USER_PARIED,
 };
 
+static irqreturn_t mp2661_chg_stat_handler(int irq, void *dev_id);
 static int mp2661_get_prop_batt_status(struct mp2661_chg *chip)
 {
-    int rc;
+    int rc, usb_present;
     u8 reg;
     int status = POWER_SUPPLY_STATUS_DISCHARGING;
     u8 chgr_sts = 0;
@@ -423,22 +424,37 @@ static int mp2661_get_prop_batt_status(struct mp2661_chg *chip)
         pr_err("Unable to read system status reg rc = %d\n", rc);
         return POWER_SUPPLY_STATUS_UNKNOWN;
     }
-    chgr_sts = (reg & CHG_STAT_MASK) >> CHG_STAT_SHIFT;
-    pr_debug("system status reg = %x\n", chgr_sts);
 
-    if ((CHG_STAT_NOT_CHARGING == chgr_sts)
-        && (!chip->repeat_charging_detect_flag))
-    {
-        status = POWER_SUPPLY_STATUS_DISCHARGING;
-    }
-    else if ((CHG_STAT_CHARGE_DONE == chgr_sts)
-            || chip->repeat_charging_detect_flag)
+    chgr_sts = (reg & CHG_STAT_MASK) >> CHG_STAT_SHIFT;
+    usb_present = (reg & CHAG_IN_VALID_IRQ) ? 1 : 0;
+    pr_info("reg = %x, chgr_sts = %d, usb_present = %d\n", reg, chgr_sts, usb_present);
+    if(usb_present)
     {
-        status = POWER_SUPPLY_STATUS_FULL;
+        if (chip->repeat_charging_detect_flag)
+        {
+            status = POWER_SUPPLY_STATUS_FULL;
+        }
+        else if (CHG_STAT_CHARGE_DONE == chgr_sts)
+        {
+            status = POWER_SUPPLY_STATUS_FULL;
+        }
+        else if (CHG_STAT_NOT_CHARGING == chgr_sts)
+        {
+            status = POWER_SUPPLY_STATUS_DISCHARGING;
+        }
+        else
+        {
+            status = POWER_SUPPLY_STATUS_CHARGING;
+        }
     }
     else
     {
-        status = POWER_SUPPLY_STATUS_CHARGING;
+        if (chip->repeat_charging_detect_flag)
+        {
+            pr_info("usb has gone, need to fix it\n");
+            mp2661_chg_stat_handler(chip->client->irq, chip);
+        }
+        status = POWER_SUPPLY_STATUS_DISCHARGING;
     }
 
     return status;
@@ -1480,6 +1496,7 @@ static void mp2661_process_interrupt_work(struct work_struct *work)
 
     /* check usb status */
     usb_present = mp2661_is_chg_plugged_in(chip);
+    pr_info("usb_present = %d, chip->usb_present = %d\n", usb_present, chip->usb_present);
     if (chip->usb_present != usb_present)
     {
         chip->usb_present = usb_present;
@@ -1608,7 +1625,7 @@ static void mp2661_process_interrupt_work(struct work_struct *work)
 static irqreturn_t mp2661_chg_stat_handler(int irq, void *dev_id)
 {
     struct mp2661_chg *chip = dev_id;
-
+    pr_info("interrupt happens\n");
     queue_work(chip->charger_int_work_queue, &chip->process_interrupt_work);
 
     return IRQ_HANDLED;
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 2e4ac8eabbc4..317a4c3e9b19 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -3386,17 +3386,12 @@ static int otg_power_get_property_usb(struct power_supply *psy,
 		break;
 	/* Reflect USB enumeration */
 	case POWER_SUPPLY_PROP_ONLINE:
-		val->intval = motg->online;
 #if CONFIG_HUAWEI_SAWSHARK
-		if(0 == val->intval)
-		{
-			/* fix online status acording to system charing status */
-			val->intval = (int)mp2661_global_is_chg_plugged_in();
-			if(val->intval != 0)
-			{
-				pr_info("fix usb status to online\n");
-			}
-		}
+		/* online status is determined by charger */
+		val->intval = (int)mp2661_global_is_chg_plugged_in();
+#else
+		val->intval = motg->online;
+
 #endif
 		break;
 	case POWER_SUPPLY_PROP_TYPE:
-- 
GitLab