aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2012-05-05 09:24:10 -0400
committerAnton Vorontsov <anton.vorontsov@linaro.org>2012-05-05 22:48:50 -0400
commitd829dc75bafb10754f35fb8895e5143d20267b04 (patch)
tree4cff2aa07dcf7c15ef931e3b9ab20a2d84fcf68d
parent34298d40e5853bc195c9db012fc1ddccac9b6f7f (diff)
charger-manager: Poll battery health in normal state
Charger-Manager needs to check battery health in normal state as well as suspend-to-RAM state. When the battery is fully charged, Charger-Manager needs to determine when the chargers restart charging. This patch allows Charger-Manager to monitor battery health in normal state and handle operation for chargers after battery is fully charged. Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com> Signed-off-by: Donggeun Kim <dg77.kim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
-rw-r--r--Documentation/power/charger-manager.txt25
-rw-r--r--drivers/power/charger-manager.c229
-rw-r--r--include/linux/power/charger-manager.h25
3 files changed, 278 insertions, 1 deletions
diff --git a/Documentation/power/charger-manager.txt b/Documentation/power/charger-manager.txt
index fdcca991df30..9b3863386e54 100644
--- a/Documentation/power/charger-manager.txt
+++ b/Documentation/power/charger-manager.txt
@@ -44,6 +44,12 @@ Charger Manager supports the following:
44 Normally, the platform will need to resume and suspend some devices 44 Normally, the platform will need to resume and suspend some devices
45 that are used by Charger Manager. 45 that are used by Charger Manager.
46 46
47* Support for premature full-battery event handling
48 If the battery voltage drops by "fullbatt_vchkdrop_uV" after
49 "fullbatt_vchkdrop_ms" from the full-battery event, the framework
50 restarts charging. This check is also performed while suspended by
51 setting wakeup time accordingly and using suspend_again.
52
472. Global Charger-Manager Data related with suspend_again 532. Global Charger-Manager Data related with suspend_again
48======================================================== 54========================================================
49In order to setup Charger Manager with suspend-again feature 55In order to setup Charger Manager with suspend-again feature
@@ -55,7 +61,7 @@ if there are multiple batteries. If there are multiple batteries, the
55multiple instances of Charger Manager share the same charger_global_desc 61multiple instances of Charger Manager share the same charger_global_desc
56and it will manage in-suspend monitoring for all instances of Charger Manager. 62and it will manage in-suspend monitoring for all instances of Charger Manager.
57 63
58The user needs to provide all the two entries properly in order to activate 64The user needs to provide all the three entries properly in order to activate
59in-suspend monitoring: 65in-suspend monitoring:
60 66
61struct charger_global_desc { 67struct charger_global_desc {
@@ -74,6 +80,11 @@ bool (*rtc_only_wakeup)(void);
74 same struct. If there is any other wakeup source triggered the 80 same struct. If there is any other wakeup source triggered the
75 wakeup, it should return false. If the "rtc" is the only wakeup 81 wakeup, it should return false. If the "rtc" is the only wakeup
76 reason, it should return true. 82 reason, it should return true.
83
84bool assume_timer_stops_in_suspend;
85 : if true, Charger Manager assumes that
86 the timer (CM uses jiffies as timer) stops during suspend. Then, CM
87 assumes that the suspend-duration is same as the alarm length.
77}; 88};
78 89
793. How to setup suspend_again 903. How to setup suspend_again
@@ -111,6 +122,16 @@ enum polling_modes polling_mode;
111 CM_POLL_CHARGING_ONLY: poll this battery if and only if the 122 CM_POLL_CHARGING_ONLY: poll this battery if and only if the
112 battery is being charged. 123 battery is being charged.
113 124
125unsigned int fullbatt_vchkdrop_ms;
126unsigned int fullbatt_vchkdrop_uV;
127 : If both have non-zero values, Charger Manager will check the
128 battery voltage drop fullbatt_vchkdrop_ms after the battery is fully
129 charged. If the voltage drop is over fullbatt_vchkdrop_uV, Charger
130 Manager will try to recharge the battery by disabling and enabling
131 chargers. Recharge with voltage drop condition only (without delay
132 condition) is needed to be implemented with hardware interrupts from
133 fuel gauges or charger devices/chips.
134
114unsigned int fullbatt_uV; 135unsigned int fullbatt_uV;
115 : If specified with a non-zero value, Charger Manager assumes 136 : If specified with a non-zero value, Charger Manager assumes
116 that the battery is full (capacity = 100) if the battery is not being 137 that the battery is full (capacity = 100) if the battery is not being
@@ -122,6 +143,8 @@ unsigned int polling_interval_ms;
122 this battery every polling_interval_ms or more frequently. 143 this battery every polling_interval_ms or more frequently.
123 144
124enum data_source battery_present; 145enum data_source battery_present;
146 : CM_BATTERY_PRESENT: assume that the battery exists.
147 CM_NO_BATTERY: assume that the battery does not exists.
125 CM_FUEL_GAUGE: get battery presence information from fuel gauge. 148 CM_FUEL_GAUGE: get battery presence information from fuel gauge.
126 CM_CHARGER_STAT: get battery presence from chargers. 149 CM_CHARGER_STAT: get battery presence from chargers.
127 150
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 9eca9f1ff0ea..959062d16bac 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -57,6 +57,12 @@ static bool cm_suspended;
57static bool cm_rtc_set; 57static bool cm_rtc_set;
58static unsigned long cm_suspend_duration_ms; 58static unsigned long cm_suspend_duration_ms;
59 59
60/* About normal (not suspended) monitoring */
61static unsigned long polling_jiffy = ULONG_MAX; /* ULONG_MAX: no polling */
62static unsigned long next_polling; /* Next appointed polling time */
63static struct workqueue_struct *cm_wq; /* init at driver add */
64static struct delayed_work cm_monitor_work; /* init at driver add */
65
60/* Global charger-manager description */ 66/* Global charger-manager description */
61static struct charger_global_desc *g_desc; /* init with setup_charger_manager */ 67static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
62 68
@@ -71,6 +77,11 @@ static bool is_batt_present(struct charger_manager *cm)
71 int i, ret; 77 int i, ret;
72 78
73 switch (cm->desc->battery_present) { 79 switch (cm->desc->battery_present) {
80 case CM_BATTERY_PRESENT:
81 present = true;
82 break;
83 case CM_NO_BATTERY:
84 break;
74 case CM_FUEL_GAUGE: 85 case CM_FUEL_GAUGE:
75 ret = cm->fuel_gauge->get_property(cm->fuel_gauge, 86 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
76 POWER_SUPPLY_PROP_PRESENT, &val); 87 POWER_SUPPLY_PROP_PRESENT, &val);
@@ -279,6 +290,26 @@ static int try_charger_enable(struct charger_manager *cm, bool enable)
279} 290}
280 291
281/** 292/**
293 * try_charger_restart - Restart charging.
294 * @cm: the Charger Manager representing the battery.
295 *
296 * Restart charging by turning off and on the charger.
297 */
298static int try_charger_restart(struct charger_manager *cm)
299{
300 int err;
301
302 if (cm->emergency_stop)
303 return -EAGAIN;
304
305 err = try_charger_enable(cm, false);
306 if (err)
307 return err;
308
309 return try_charger_enable(cm, true);
310}
311
312/**
282 * uevent_notify - Let users know something has changed. 313 * uevent_notify - Let users know something has changed.
283 * @cm: the Charger Manager representing the battery. 314 * @cm: the Charger Manager representing the battery.
284 * @event: the event string. 315 * @event: the event string.
@@ -334,6 +365,46 @@ static void uevent_notify(struct charger_manager *cm, const char *event)
334} 365}
335 366
336/** 367/**
368 * fullbatt_vchk - Check voltage drop some times after "FULL" event.
369 * @work: the work_struct appointing the function
370 *
371 * If a user has designated "fullbatt_vchkdrop_ms/uV" values with
372 * charger_desc, Charger Manager checks voltage drop after the battery
373 * "FULL" event. It checks whether the voltage has dropped more than
374 * fullbatt_vchkdrop_uV by calling this function after fullbatt_vchkrop_ms.
375 */
376static void fullbatt_vchk(struct work_struct *work)
377{
378 struct delayed_work *dwork = to_delayed_work(work);
379 struct charger_manager *cm = container_of(dwork,
380 struct charger_manager, fullbatt_vchk_work);
381 struct charger_desc *desc = cm->desc;
382 int batt_uV, err, diff;
383
384 /* remove the appointment for fullbatt_vchk */
385 cm->fullbatt_vchk_jiffies_at = 0;
386
387 if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
388 return;
389
390 err = get_batt_uV(cm, &batt_uV);
391 if (err) {
392 dev_err(cm->dev, "%s: get_batt_uV error(%d).\n", __func__, err);
393 return;
394 }
395
396 diff = cm->fullbatt_vchk_uV;
397 diff -= batt_uV;
398
399 dev_dbg(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
400
401 if (diff > desc->fullbatt_vchkdrop_uV) {
402 try_charger_restart(cm);
403 uevent_notify(cm, "Recharge");
404 }
405}
406
407/**
337 * _cm_monitor - Monitor the temperature and return true for exceptions. 408 * _cm_monitor - Monitor the temperature and return true for exceptions.
338 * @cm: the Charger Manager representing the battery. 409 * @cm: the Charger Manager representing the battery.
339 * 410 *
@@ -392,6 +463,68 @@ static bool cm_monitor(void)
392 return stop; 463 return stop;
393} 464}
394 465
466/**
467 * _setup_polling - Setup the next instance of polling.
468 * @work: work_struct of the function _setup_polling.
469 */
470static void _setup_polling(struct work_struct *work)
471{
472 unsigned long min = ULONG_MAX;
473 struct charger_manager *cm;
474 bool keep_polling = false;
475 unsigned long _next_polling;
476
477 mutex_lock(&cm_list_mtx);
478
479 list_for_each_entry(cm, &cm_list, entry) {
480 if (is_polling_required(cm) && cm->desc->polling_interval_ms) {
481 keep_polling = true;
482
483 if (min > cm->desc->polling_interval_ms)
484 min = cm->desc->polling_interval_ms;
485 }
486 }
487
488 polling_jiffy = msecs_to_jiffies(min);
489 if (polling_jiffy <= CM_JIFFIES_SMALL)
490 polling_jiffy = CM_JIFFIES_SMALL + 1;
491
492 if (!keep_polling)
493 polling_jiffy = ULONG_MAX;
494 if (polling_jiffy == ULONG_MAX)
495 goto out;
496
497 WARN(cm_wq == NULL, "charger-manager: workqueue not initialized"
498 ". try it later. %s\n", __func__);
499
500 _next_polling = jiffies + polling_jiffy;
501
502 if (!delayed_work_pending(&cm_monitor_work) ||
503 (delayed_work_pending(&cm_monitor_work) &&
504 time_after(next_polling, _next_polling))) {
505 cancel_delayed_work_sync(&cm_monitor_work);
506 next_polling = jiffies + polling_jiffy;
507 queue_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy);
508 }
509
510out:
511 mutex_unlock(&cm_list_mtx);
512}
513static DECLARE_WORK(setup_polling, _setup_polling);
514
515/**
516 * cm_monitor_poller - The Monitor / Poller.
517 * @work: work_struct of the function cm_monitor_poller
518 *
519 * During non-suspended state, cm_monitor_poller is used to poll and monitor
520 * the batteries.
521 */
522static void cm_monitor_poller(struct work_struct *work)
523{
524 cm_monitor();
525 schedule_work(&setup_polling);
526}
527
395static int charger_get_property(struct power_supply *psy, 528static int charger_get_property(struct power_supply *psy,
396 enum power_supply_property psp, 529 enum power_supply_property psp,
397 union power_supply_propval *val) 530 union power_supply_propval *val)
@@ -613,6 +746,21 @@ static bool cm_setup_timer(void)
613 mutex_lock(&cm_list_mtx); 746 mutex_lock(&cm_list_mtx);
614 747
615 list_for_each_entry(cm, &cm_list, entry) { 748 list_for_each_entry(cm, &cm_list, entry) {
749 unsigned int fbchk_ms = 0;
750
751 /* fullbatt_vchk is required. setup timer for that */
752 if (cm->fullbatt_vchk_jiffies_at) {
753 fbchk_ms = jiffies_to_msecs(cm->fullbatt_vchk_jiffies_at
754 - jiffies);
755 if (time_is_before_eq_jiffies(
756 cm->fullbatt_vchk_jiffies_at) ||
757 msecs_to_jiffies(fbchk_ms) < CM_JIFFIES_SMALL) {
758 fullbatt_vchk(&cm->fullbatt_vchk_work.work);
759 fbchk_ms = 0;
760 }
761 }
762 CM_MIN_VALID(wakeup_ms, fbchk_ms);
763
616 /* Skip if polling is not required for this CM */ 764 /* Skip if polling is not required for this CM */
617 if (!is_polling_required(cm) && !cm->emergency_stop) 765 if (!is_polling_required(cm) && !cm->emergency_stop)
618 continue; 766 continue;
@@ -672,6 +820,23 @@ static bool cm_setup_timer(void)
672 return false; 820 return false;
673} 821}
674 822
823static void _cm_fbchk_in_suspend(struct charger_manager *cm)
824{
825 unsigned long jiffy_now = jiffies;
826
827 if (!cm->fullbatt_vchk_jiffies_at)
828 return;
829
830 if (g_desc && g_desc->assume_timer_stops_in_suspend)
831 jiffy_now += msecs_to_jiffies(cm_suspend_duration_ms);
832
833 /* Execute now if it's going to be executed not too long after */
834 jiffy_now += CM_JIFFIES_SMALL;
835
836 if (time_after_eq(jiffy_now, cm->fullbatt_vchk_jiffies_at))
837 fullbatt_vchk(&cm->fullbatt_vchk_work.work);
838}
839
675/** 840/**
676 * cm_suspend_again - Determine whether suspend again or not 841 * cm_suspend_again - Determine whether suspend again or not
677 * 842 *
@@ -693,6 +858,8 @@ bool cm_suspend_again(void)
693 ret = true; 858 ret = true;
694 mutex_lock(&cm_list_mtx); 859 mutex_lock(&cm_list_mtx);
695 list_for_each_entry(cm, &cm_list, entry) { 860 list_for_each_entry(cm, &cm_list, entry) {
861 _cm_fbchk_in_suspend(cm);
862
696 if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) || 863 if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) ||
697 cm->status_save_batt != is_batt_present(cm)) { 864 cm->status_save_batt != is_batt_present(cm)) {
698 ret = false; 865 ret = false;
@@ -796,6 +963,21 @@ static int charger_manager_probe(struct platform_device *pdev)
796 memcpy(cm->desc, desc, sizeof(struct charger_desc)); 963 memcpy(cm->desc, desc, sizeof(struct charger_desc));
797 cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */ 964 cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
798 965
966 /*
967 * The following two do not need to be errors.
968 * Users may intentionally ignore those two features.
969 */
970 if (desc->fullbatt_uV == 0) {
971 dev_info(&pdev->dev, "Ignoring full-battery voltage threshold"
972 " as it is not supplied.");
973 }
974 if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) {
975 dev_info(&pdev->dev, "Disabling full-battery voltage drop "
976 "checking mechanism as it is not supplied.");
977 desc->fullbatt_vchkdrop_ms = 0;
978 desc->fullbatt_vchkdrop_uV = 0;
979 }
980
799 if (!desc->charger_regulators || desc->num_charger_regulators < 1) { 981 if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
800 ret = -EINVAL; 982 ret = -EINVAL;
801 dev_err(&pdev->dev, "charger_regulators undefined.\n"); 983 dev_err(&pdev->dev, "charger_regulators undefined.\n");
@@ -903,6 +1085,8 @@ static int charger_manager_probe(struct platform_device *pdev)
903 cm->charger_psy.num_properties++; 1085 cm->charger_psy.num_properties++;
904 } 1086 }
905 1087
1088 INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
1089
906 ret = power_supply_register(NULL, &cm->charger_psy); 1090 ret = power_supply_register(NULL, &cm->charger_psy);
907 if (ret) { 1091 if (ret) {
908 dev_err(&pdev->dev, "Cannot register charger-manager with" 1092 dev_err(&pdev->dev, "Cannot register charger-manager with"
@@ -928,6 +1112,8 @@ static int charger_manager_probe(struct platform_device *pdev)
928 list_add(&cm->entry, &cm_list); 1112 list_add(&cm->entry, &cm_list);
929 mutex_unlock(&cm_list_mtx); 1113 mutex_unlock(&cm_list_mtx);
930 1114
1115 schedule_work(&setup_polling);
1116
931 return 0; 1117 return 0;
932 1118
933err_chg_enable: 1119err_chg_enable:
@@ -958,9 +1144,17 @@ static int __devexit charger_manager_remove(struct platform_device *pdev)
958 list_del(&cm->entry); 1144 list_del(&cm->entry);
959 mutex_unlock(&cm_list_mtx); 1145 mutex_unlock(&cm_list_mtx);
960 1146
1147 if (work_pending(&setup_polling))
1148 cancel_work_sync(&setup_polling);
1149 if (delayed_work_pending(&cm_monitor_work))
1150 cancel_delayed_work_sync(&cm_monitor_work);
1151
961 regulator_bulk_free(desc->num_charger_regulators, 1152 regulator_bulk_free(desc->num_charger_regulators,
962 desc->charger_regulators); 1153 desc->charger_regulators);
963 power_supply_unregister(&cm->charger_psy); 1154 power_supply_unregister(&cm->charger_psy);
1155
1156 try_charger_enable(cm, false);
1157
964 kfree(cm->charger_psy.properties); 1158 kfree(cm->charger_psy.properties);
965 kfree(cm->charger_stat); 1159 kfree(cm->charger_stat);
966 kfree(cm->desc); 1160 kfree(cm->desc);
@@ -1000,6 +1194,8 @@ static int cm_suspend_prepare(struct device *dev)
1000 cm_suspended = true; 1194 cm_suspended = true;
1001 } 1195 }
1002 1196
1197 if (delayed_work_pending(&cm->fullbatt_vchk_work))
1198 cancel_delayed_work(&cm->fullbatt_vchk_work);
1003 cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm); 1199 cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm);
1004 cm->status_save_batt = is_batt_present(cm); 1200 cm->status_save_batt = is_batt_present(cm);
1005 1201
@@ -1027,6 +1223,33 @@ static void cm_suspend_complete(struct device *dev)
1027 cm_rtc_set = false; 1223 cm_rtc_set = false;
1028 } 1224 }
1029 1225
1226 /* Re-enqueue delayed work (fullbatt_vchk_work) */
1227 if (cm->fullbatt_vchk_jiffies_at) {
1228 unsigned long delay = 0;
1229 unsigned long now = jiffies + CM_JIFFIES_SMALL;
1230
1231 if (time_after_eq(now, cm->fullbatt_vchk_jiffies_at)) {
1232 delay = (unsigned long)((long)now
1233 - (long)(cm->fullbatt_vchk_jiffies_at));
1234 delay = jiffies_to_msecs(delay);
1235 } else {
1236 delay = 0;
1237 }
1238
1239 /*
1240 * Account for cm_suspend_duration_ms if
1241 * assume_timer_stops_in_suspend is active
1242 */
1243 if (g_desc && g_desc->assume_timer_stops_in_suspend) {
1244 if (delay > cm_suspend_duration_ms)
1245 delay -= cm_suspend_duration_ms;
1246 else
1247 delay = 0;
1248 }
1249
1250 queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
1251 msecs_to_jiffies(delay));
1252 }
1030 uevent_notify(cm, NULL); 1253 uevent_notify(cm, NULL);
1031} 1254}
1032 1255
@@ -1048,12 +1271,18 @@ static struct platform_driver charger_manager_driver = {
1048 1271
1049static int __init charger_manager_init(void) 1272static int __init charger_manager_init(void)
1050{ 1273{
1274 cm_wq = create_freezable_workqueue("charger_manager");
1275 INIT_DELAYED_WORK(&cm_monitor_work, cm_monitor_poller);
1276
1051 return platform_driver_register(&charger_manager_driver); 1277 return platform_driver_register(&charger_manager_driver);
1052} 1278}
1053late_initcall(charger_manager_init); 1279late_initcall(charger_manager_init);
1054 1280
1055static void __exit charger_manager_cleanup(void) 1281static void __exit charger_manager_cleanup(void)
1056{ 1282{
1283 destroy_workqueue(cm_wq);
1284 cm_wq = NULL;
1285
1057 platform_driver_unregister(&charger_manager_driver); 1286 platform_driver_unregister(&charger_manager_driver);
1058} 1287}
1059module_exit(charger_manager_cleanup); 1288module_exit(charger_manager_cleanup);
diff --git a/include/linux/power/charger-manager.h b/include/linux/power/charger-manager.h
index 4f75e531c112..baa299a95e13 100644
--- a/include/linux/power/charger-manager.h
+++ b/include/linux/power/charger-manager.h
@@ -18,6 +18,8 @@
18#include <linux/power_supply.h> 18#include <linux/power_supply.h>
19 19
20enum data_source { 20enum data_source {
21 CM_BATTERY_PRESENT,
22 CM_NO_BATTERY,
21 CM_FUEL_GAUGE, 23 CM_FUEL_GAUGE,
22 CM_CHARGER_STAT, 24 CM_CHARGER_STAT,
23}; 25};
@@ -38,11 +40,18 @@ enum polling_modes {
38 * rtc_only_wakeup() returning false. 40 * rtc_only_wakeup() returning false.
39 * If the RTC given to CM is the only wakeup reason, 41 * If the RTC given to CM is the only wakeup reason,
40 * rtc_only_wakeup should return true. 42 * rtc_only_wakeup should return true.
43 * @assume_timer_stops_in_suspend:
44 * Assume that the jiffy timer stops in suspend-to-RAM.
45 * When enabled, CM does not rely on jiffies value in
46 * suspend_again and assumes that jiffies value does not
47 * change during suspend.
41 */ 48 */
42struct charger_global_desc { 49struct charger_global_desc {
43 char *rtc_name; 50 char *rtc_name;
44 51
45 bool (*rtc_only_wakeup)(void); 52 bool (*rtc_only_wakeup)(void);
53
54 bool assume_timer_stops_in_suspend;
46}; 55};
47 56
48/** 57/**
@@ -50,6 +59,11 @@ struct charger_global_desc {
50 * @psy_name: the name of power-supply-class for charger manager 59 * @psy_name: the name of power-supply-class for charger manager
51 * @polling_mode: 60 * @polling_mode:
52 * Determine which polling mode will be used 61 * Determine which polling mode will be used
62 * @fullbatt_vchkdrop_ms:
63 * @fullbatt_vchkdrop_uV:
64 * Check voltage drop after the battery is fully charged.
65 * If it has dropped more than fullbatt_vchkdrop_uV after
66 * fullbatt_vchkdrop_ms, CM will restart charging.
53 * @fullbatt_uV: voltage in microvolt 67 * @fullbatt_uV: voltage in microvolt
54 * If it is not being charged and VBATT >= fullbatt_uV, 68 * If it is not being charged and VBATT >= fullbatt_uV,
55 * it is assumed to be full. 69 * it is assumed to be full.
@@ -76,6 +90,8 @@ struct charger_desc {
76 enum polling_modes polling_mode; 90 enum polling_modes polling_mode;
77 unsigned int polling_interval_ms; 91 unsigned int polling_interval_ms;
78 92
93 unsigned int fullbatt_vchkdrop_ms;
94 unsigned int fullbatt_vchkdrop_uV;
79 unsigned int fullbatt_uV; 95 unsigned int fullbatt_uV;
80 96
81 enum data_source battery_present; 97 enum data_source battery_present;
@@ -101,6 +117,11 @@ struct charger_desc {
101 * @fuel_gauge: power_supply for fuel gauge 117 * @fuel_gauge: power_supply for fuel gauge
102 * @charger_stat: array of power_supply for chargers 118 * @charger_stat: array of power_supply for chargers
103 * @charger_enabled: the state of charger 119 * @charger_enabled: the state of charger
120 * @fullbatt_vchk_jiffies_at:
121 * jiffies at the time full battery check will occur.
122 * @fullbatt_vchk_uV: voltage in microvolt
123 * criteria for full battery
124 * @fullbatt_vchk_work: work queue for full battery check
104 * @emergency_stop: 125 * @emergency_stop:
105 * When setting true, stop charging 126 * When setting true, stop charging
106 * @last_temp_mC: the measured temperature in milli-Celsius 127 * @last_temp_mC: the measured temperature in milli-Celsius
@@ -121,6 +142,10 @@ struct charger_manager {
121 142
122 bool charger_enabled; 143 bool charger_enabled;
123 144
145 unsigned long fullbatt_vchk_jiffies_at;
146 unsigned int fullbatt_vchk_uV;
147 struct delayed_work fullbatt_vchk_work;
148
124 int emergency_stop; 149 int emergency_stop;
125 int last_temp_mC; 150 int last_temp_mC;
126 151