summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/power/ab8500_chargalg.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/power/ab8500_chargalg.c b/drivers/power/ab8500_chargalg.c
index cb56c67475c..97ea736424a 100644
--- a/drivers/power/ab8500_chargalg.c
+++ b/drivers/power/ab8500_chargalg.c
@@ -399,7 +399,8 @@ static void ab8500_chargalg_start_safety_timer(struct ab8500_chargalg *di)
static void ab8500_chargalg_stop_safety_timer(struct ab8500_chargalg *di)
{
di->events.safety_timer_expired = false;
- del_timer(&di->safety_timer);
+ if (timer_pending(&di->safety_timer))
+ del_timer(&di->safety_timer);
}
/**
@@ -851,6 +852,27 @@ static void handle_maxim_chg_curr(struct ab8500_chargalg *di)
}
}
+static void ab8500_chargalg_check_safety_timer(struct ab8500_chargalg *di)
+{
+ /*
+ * The safety timer will not be started until the capacity reported
+ * from the FG algorithm is 100%. Then we know that the amount of
+ * charge that's gone into the battery is enough for the battery
+ * to be full. If it has not reached end-of-charge before the safety
+ * timer has expired then we know that the battery is overcharged
+ * and charging will be stopped to protect the battery.
+ */
+ if (di->batt_data.percent == 100 &&
+ !timer_pending(&di->safety_timer)) {
+ ab8500_chargalg_start_safety_timer(di);
+ dev_dbg(di->dev, "start safety timer\n");
+ } else if (di->batt_data.percent != 100 &&
+ timer_pending(&di->safety_timer)) {
+ ab8500_chargalg_stop_safety_timer(di);
+ dev_dbg(di->dev, "stop safety timer\n");
+ }
+}
+
static int ab8500_chargalg_get_ext_psy_data(struct device *dev, void *data)
{
struct power_supply *psy;
@@ -1401,7 +1423,6 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
di->bat->bat_type[di->bat->batt_id].normal_vol_lvl,
di->bat->bat_type[di->bat->batt_id].normal_cur_lvl);
ab8500_chargalg_state_to(di, STATE_NORMAL);
- ab8500_chargalg_start_safety_timer(di);
ab8500_chargalg_stop_maintenance_timer(di);
init_maxim_chg_curr(di);
di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
@@ -1422,6 +1443,8 @@ static void ab8500_chargalg_algorithm(struct ab8500_chargalg *di)
ab8500_chargalg_state_to(di,
STATE_MAINTENANCE_A_INIT);
}
+ /* Check whether we should start the safety timer or not */
+ ab8500_chargalg_check_safety_timer(di);
break;
/* This state will be used when the maintenance state is disabled */