power: tps80031: charger: handle re-charge event
Xin Xie [Fri, 13 Jul 2012 01:26:59 +0000 (18:26 -0700)]
After the charging completed, TPS80031 can re-enable the charging if it
sense the voltage dropping (120mV below target). Current drive does not
handle this event and causing the charging forever stopped.

This patch will check the above re-charging happens in the charging WDT
handler, and will ack WDT in order to continue charging.

BUG 1015045

Change-Id: Ia0a53d29cd0e73e7ebcd53f8176c8ef81b6c6090
Signed-off-by: Xin Xie <xxie@nvidia.com>
Reviewed-on: http://git-master/r/122309
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>

drivers/power/tps80031-charger.c

index edbcfcc..9190b72 100644 (file)
@@ -294,27 +294,41 @@ static int configure_charging_parameter(struct tps80031_charger *charger)
        return 0;
 }
 
-static irqreturn_t linch_status_isr(int irq, void *dev_id)
+static bool tps80031_check_charging_completed(struct tps80031_charger *charger)
 {
-       struct tps80031_charger *charger = dev_id;
-       uint8_t linch_status;
        int ret;
-       dev_info(charger->dev, "%s() got called\n", __func__);
+       uint8_t linch_status;
 
        ret = tps80031_read(charger->dev->parent, SLAVE_ID2,
                        LINEAR_CHRG_STS, &linch_status);
        if (ret < 0) {
                dev_err(charger->dev, "%s(): Failed in reading register 0x%02x\n",
                                __func__, LINEAR_CHRG_STS);
+               return false;
+       }
+
+       if (linch_status & 0x20) {
+               charger->state = charging_state_charging_completed;
+               ret = true;
        } else {
-               dev_info(charger->dev, "%s():The status of LINEAR_CHRG_STS is 0x%02x\n",
-                                __func__, linch_status);
-               if (linch_status & 0x20) {
-                       charger->state = charging_state_charging_completed;
-                       if (charger->charger_cb)
-                               charger->charger_cb(charger->state,
+               charger->state = charging_state_charging_in_progress;
+               ret = false;
+       }
+
+       return ret;
+}
+
+static irqreturn_t linch_status_isr(int irq, void *dev_id)
+{
+       struct tps80031_charger *charger = dev_id;
+
+       dev_info(charger->dev, "%s() got called\n", __func__);
+
+       if (tps80031_check_charging_completed(charger)) {
+               charger->state = charging_state_charging_completed;
+               if (charger->charger_cb)
+                       charger->charger_cb(charger->state,
                                        charger->charger_cb_data);
-               }
        }
 
        return IRQ_HANDLED;
@@ -326,8 +340,22 @@ static irqreturn_t watchdog_expire_isr(int irq, void *dev_id)
        int ret;
 
        dev_info(charger->dev, "%s()\n", __func__);
-       if (charger->state != charging_state_charging_in_progress)
-               return IRQ_HANDLED;
+       if (charger->state != charging_state_charging_in_progress) {
+               /*
+                * After the charge completed, the chip can enable the
+                * charging again if battery voltage is 120mV below the
+                * charging voltage (defined by VOREG register).
+                */
+               if (tps80031_check_charging_completed(charger)) {
+                       return IRQ_HANDLED;
+               } else {
+                       /* "recharging" after charging completed happened */
+                       charger->state = charging_state_charging_in_progress;
+                       if (charger->charger_cb)
+                               charger->charger_cb(charger->state,
+                                               charger->charger_cb_data);
+               }
+       }
 
        /* Enable watchdog timer again*/
        ret = tps80031_write(charger->dev->parent, SLAVE_ID2, CONTROLLER_WDG,