Lines Matching +full:monitor +full:- +full:interval +full:- +full:ms

1 // SPDX-License-Identifier: GPL-2.0-only
6 * This driver enables to monitor battery health and control charger
7 * during suspend-to-mem.
23 #include <linux/power/charger-manager.h>
35 { "USB-HOST", EXTCON_USB_HOST },
40 { "FAST-CHARGER", EXTCON_CHG_USB_FAST },
41 { "SLOW-CHARGER", EXTCON_CHG_USB_SLOW },
49 { "CHARGE-DOWNSTREAM", EXTCON_CHG_USB_CDP },
78 /* About in-suspend (suspend-again) monitoring */
92 * is_batt_present - See if the battery presents in place.
102 switch (cm->desc->battery_present) { in is_batt_present()
109 psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in is_batt_present()
120 for (i = 0; cm->desc->psy_charger_stat[i]; i++) { in is_batt_present()
122 cm->desc->psy_charger_stat[i]); in is_batt_present()
124 dev_err(cm->dev, "Cannot find power supply \"%s\"\n", in is_batt_present()
125 cm->desc->psy_charger_stat[i]); in is_batt_present()
144 * is_ext_pwr_online - See if an external power source is attached to charge
159 for (i = 0; cm->desc->psy_charger_stat[i]; i++) { in is_ext_pwr_online()
160 psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]); in is_ext_pwr_online()
162 dev_err(cm->dev, "Cannot find power supply \"%s\"\n", in is_ext_pwr_online()
163 cm->desc->psy_charger_stat[i]); in is_ext_pwr_online()
180 * get_batt_uV - Get the voltage level of the battery
193 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in get_batt_uV()
195 return -ENODEV; in get_batt_uV()
208 * is_charging - Returns true if the battery is being charged.
223 for (i = 0; cm->desc->psy_charger_stat[i]; i++) { in is_charging()
225 if (cm->emergency_stop) in is_charging()
227 if (!cm->charger_enabled) in is_charging()
230 psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]); in is_charging()
232 dev_err(cm->dev, "Cannot find power supply \"%s\"\n", in is_charging()
233 cm->desc->psy_charger_stat[i]); in is_charging()
237 /* 2. The charger should be online (ext-power) */ in is_charging()
241 dev_warn(cm->dev, "Cannot read ONLINE value from %s\n", in is_charging()
242 cm->desc->psy_charger_stat[i]); in is_charging()
259 dev_warn(cm->dev, "Cannot read STATUS value from %s\n", in is_charging()
260 cm->desc->psy_charger_stat[i]); in is_charging()
277 * is_full_charged - Returns true if the battery is fully charged.
282 struct charger_desc *desc = cm->desc; in is_full_charged()
293 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in is_full_charged()
298 if (desc->fullbatt_uV > 0) { in is_full_charged()
302 if (cm->battery_status == POWER_SUPPLY_STATUS_FULL in is_full_charged()
303 && desc->fullbatt_vchkdrop_uV) in is_full_charged()
304 uV += desc->fullbatt_vchkdrop_uV; in is_full_charged()
305 if (uV >= desc->fullbatt_uV) in is_full_charged()
310 if (desc->fullbatt_full_capacity > 0) { in is_full_charged()
316 if (!ret && val.intval > desc->fullbatt_full_capacity) { in is_full_charged()
323 if (desc->fullbatt_soc > 0) { in is_full_charged()
328 if (!ret && val.intval >= desc->fullbatt_soc) { in is_full_charged()
340 * is_polling_required - Return true if need to continue polling for this CM.
345 switch (cm->desc->polling_mode) { in is_polling_required()
355 dev_warn(cm->dev, "Incorrect polling_mode (%d)\n", in is_polling_required()
356 cm->desc->polling_mode); in is_polling_required()
363 * try_charger_enable - Enable/Disable chargers altogether
375 struct charger_desc *desc = cm->desc; in try_charger_enable()
378 if (enable == cm->charger_enabled) in try_charger_enable()
382 if (cm->emergency_stop) in try_charger_enable()
383 return -EAGAIN; in try_charger_enable()
389 cm->charging_start_time = ktime_to_ms(ktime_get()); in try_charger_enable()
390 cm->charging_end_time = 0; in try_charger_enable()
392 for (i = 0 ; i < desc->num_charger_regulators ; i++) { in try_charger_enable()
393 if (desc->charger_regulators[i].externally_control) in try_charger_enable()
396 err = regulator_enable(desc->charger_regulators[i].consumer); in try_charger_enable()
398 dev_warn(cm->dev, "Cannot enable %s regulator\n", in try_charger_enable()
399 desc->charger_regulators[i].regulator_name); in try_charger_enable()
405 * of battery after full-batt. in try_charger_enable()
407 cm->charging_start_time = 0; in try_charger_enable()
408 cm->charging_end_time = ktime_to_ms(ktime_get()); in try_charger_enable()
410 for (i = 0 ; i < desc->num_charger_regulators ; i++) { in try_charger_enable()
411 if (desc->charger_regulators[i].externally_control) in try_charger_enable()
414 err = regulator_disable(desc->charger_regulators[i].consumer); in try_charger_enable()
416 dev_warn(cm->dev, "Cannot disable %s regulator\n", in try_charger_enable()
417 desc->charger_regulators[i].regulator_name); in try_charger_enable()
422 * Abnormal battery state - Stop charging forcibly, in try_charger_enable()
425 for (i = 0; i < desc->num_charger_regulators; i++) { in try_charger_enable()
427 desc->charger_regulators[i].consumer)) { in try_charger_enable()
429 desc->charger_regulators[i].consumer); in try_charger_enable()
430 dev_warn(cm->dev, "Disable regulator(%s) forcibly\n", in try_charger_enable()
431 desc->charger_regulators[i].regulator_name); in try_charger_enable()
437 cm->charger_enabled = enable; in try_charger_enable()
443 * check_charging_duration - Monitor charging/discharging duration
449 * attached, after full-batt, cm start charging to maintain fully
454 struct charger_desc *desc = cm->desc; in check_charging_duration()
459 if (!desc->charging_max_duration_ms && in check_charging_duration()
460 !desc->discharging_max_duration_ms) in check_charging_duration()
463 if (cm->charger_enabled) { in check_charging_duration()
464 duration = curr - cm->charging_start_time; in check_charging_duration()
466 if (duration > desc->charging_max_duration_ms) { in check_charging_duration()
467 dev_info(cm->dev, "Charging duration exceed %ums\n", in check_charging_duration()
468 desc->charging_max_duration_ms); in check_charging_duration()
471 } else if (cm->battery_status == POWER_SUPPLY_STATUS_NOT_CHARGING) { in check_charging_duration()
472 duration = curr - cm->charging_end_time; in check_charging_duration()
474 if (duration > desc->discharging_max_duration_ms) { in check_charging_duration()
475 dev_info(cm->dev, "Discharging duration exceed %ums\n", in check_charging_duration()
476 desc->discharging_max_duration_ms); in check_charging_duration()
490 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in cm_get_battery_temperature_by_psy()
492 return -ENODEV; in cm_get_battery_temperature_by_psy()
507 if (!cm->desc->measure_battery_temp) in cm_get_battery_temperature()
508 return -ENODEV; in cm_get_battery_temperature()
511 if (cm->tzd_batt) { in cm_get_battery_temperature()
512 ret = thermal_zone_get_temp(cm->tzd_batt, temp); in cm_get_battery_temperature()
519 /* if-else continued from CONFIG_THERMAL */ in cm_get_battery_temperature()
528 struct charger_desc *desc = cm->desc; in cm_check_thermal_status()
539 dev_err(cm->dev, "Failed to get battery temperature\n"); in cm_check_thermal_status()
543 upper_limit = desc->temp_max; in cm_check_thermal_status()
544 lower_limit = desc->temp_min; in cm_check_thermal_status()
546 if (cm->emergency_stop) { in cm_check_thermal_status()
547 upper_limit -= desc->temp_diff; in cm_check_thermal_status()
548 lower_limit += desc->temp_diff; in cm_check_thermal_status()
558 cm->emergency_stop = ret; in cm_check_thermal_status()
564 * cm_get_target_status - Check current status and get next target status.
579 switch (cm->battery_status) { in cm_get_target_status()
599 * _cm_monitor - Monitor the temperature and return true for exceptions.
613 if (cm->battery_status != target) { in _cm_monitor()
614 cm->battery_status = target; in _cm_monitor()
615 power_supply_changed(cm->charger_psy); in _cm_monitor()
618 return (cm->battery_status == POWER_SUPPLY_STATUS_NOT_CHARGING); in _cm_monitor()
622 * cm_monitor - Monitor every battery.
645 * _setup_polling - Setup the next instance of polling.
658 if (is_polling_required(cm) && cm->desc->polling_interval_ms) { in _setup_polling()
661 if (min > cm->desc->polling_interval_ms) in _setup_polling()
662 min = cm->desc->polling_interval_ms; in _setup_polling()
675 WARN(cm_wq == NULL, "charger-manager: workqueue not initialized" in _setup_polling()
679 * Use mod_delayed_work() iff the next polling interval should in _setup_polling()
699 * cm_monitor_poller - The Monitor / Poller.
702 * During non-suspended state, cm_monitor_poller is used to poll and monitor
716 struct charger_desc *desc = cm->desc; in charger_get_property()
723 val->intval = cm->battery_status; in charger_get_property()
726 if (cm->emergency_stop > 0) in charger_get_property()
727 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in charger_get_property()
728 else if (cm->emergency_stop < 0) in charger_get_property()
729 val->intval = POWER_SUPPLY_HEALTH_COLD; in charger_get_property()
731 val->intval = POWER_SUPPLY_HEALTH_GOOD; in charger_get_property()
735 val->intval = 1; in charger_get_property()
737 val->intval = 0; in charger_get_property()
740 ret = get_batt_uV(cm, &val->intval); in charger_get_property()
743 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in charger_get_property()
745 ret = -ENODEV; in charger_get_property()
752 return cm_get_battery_temperature(cm, &val->intval); in charger_get_property()
756 val->intval = 100; in charger_get_property()
760 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in charger_get_property()
762 ret = -ENODEV; in charger_get_property()
771 if (val->intval > 100) { in charger_get_property()
772 val->intval = 100; in charger_get_property()
775 if (val->intval < 0) in charger_get_property()
776 val->intval = 0; in charger_get_property()
793 if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV && in charger_get_property()
795 val->intval = 100; in charger_get_property()
802 val->intval = 1; in charger_get_property()
804 val->intval = 0; in charger_get_property()
808 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in charger_get_property()
810 ret = -ENODEV; in charger_get_property()
816 return -EINVAL; in charger_get_property()
851 * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
868 jiffies_to_msecs(next_polling - jiffies)); in cm_setup_timer()
873 if (!is_polling_required(cm) && !cm->emergency_stop) in cm_setup_timer()
876 if (cm->desc->polling_interval_ms == 0) in cm_setup_timer()
878 CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms); in cm_setup_timer()
886 * Set alarm with the polling interval (wakeup_ms) in cm_setup_timer()
893 pr_info("Charger Manager wakeup timer: %u ms\n", wakeup_ms); in cm_setup_timer()
908 * charger_extcon_work - enable/diable charger according to the state
919 if (cable->attached && cable->min_uA != 0 && cable->max_uA != 0) { in charger_extcon_work()
920 ret = regulator_set_current_limit(cable->charger->consumer, in charger_extcon_work()
921 cable->min_uA, cable->max_uA); in charger_extcon_work()
924 cable->charger->regulator_name, cable->name); in charger_extcon_work()
929 cable->charger->regulator_name, in charger_extcon_work()
930 cable->min_uA, cable->max_uA); in charger_extcon_work()
938 * charger_extcon_notifier - receive the state of charger cable
953 * If cable is attached, cable->attached is true. in charger_extcon_notifier()
955 cable->attached = event; in charger_extcon_notifier()
961 schedule_work(&cable->wq); in charger_extcon_notifier()
967 * charger_extcon_init - register external connector to use it
984 INIT_WORK(&cable->wq, charger_extcon_work); in charger_extcon_init()
985 cable->nb.notifier_call = charger_extcon_notifier; in charger_extcon_init()
987 cable->extcon_dev = extcon_get_extcon_dev(cable->extcon_name); in charger_extcon_init()
988 if (IS_ERR_OR_NULL(cable->extcon_dev)) { in charger_extcon_init()
990 cable->extcon_name, cable->name); in charger_extcon_init()
991 if (cable->extcon_dev == NULL) in charger_extcon_init()
992 return -EPROBE_DEFER; in charger_extcon_init()
994 return PTR_ERR(cable->extcon_dev); in charger_extcon_init()
998 if (!strcmp(cable->name, extcon_mapping[i].name)) { in charger_extcon_init()
1004 pr_err("Cannot find cable for type %s", cable->name); in charger_extcon_init()
1005 return -EINVAL; in charger_extcon_init()
1008 cable->extcon_type = extcon_type; in charger_extcon_init()
1010 ret = devm_extcon_register_notifier(cm->dev, cable->extcon_dev, in charger_extcon_init()
1011 cable->extcon_type, &cable->nb); in charger_extcon_init()
1014 cable->extcon_name, cable->name); in charger_extcon_init()
1022 * charger_manager_register_extcon - Register extcon device to receive state
1033 struct charger_desc *desc = cm->desc; in charger_manager_register_extcon()
1040 for (i = 0; i < desc->num_charger_regulators; i++) { in charger_manager_register_extcon()
1041 charger = &desc->charger_regulators[i]; in charger_manager_register_extcon()
1043 charger->consumer = regulator_get(cm->dev, in charger_manager_register_extcon()
1044 charger->regulator_name); in charger_manager_register_extcon()
1045 if (IS_ERR(charger->consumer)) { in charger_manager_register_extcon()
1046 dev_err(cm->dev, "Cannot find charger(%s)\n", in charger_manager_register_extcon()
1047 charger->regulator_name); in charger_manager_register_extcon()
1048 return PTR_ERR(charger->consumer); in charger_manager_register_extcon()
1050 charger->cm = cm; in charger_manager_register_extcon()
1052 for (j = 0; j < charger->num_cables; j++) { in charger_manager_register_extcon()
1053 struct charger_cable *cable = &charger->cables[j]; in charger_manager_register_extcon()
1057 dev_err(cm->dev, "Cannot initialize charger(%s)\n", in charger_manager_register_extcon()
1058 charger->regulator_name); in charger_manager_register_extcon()
1061 cable->charger = charger; in charger_manager_register_extcon()
1062 cable->cm = cm; in charger_manager_register_extcon()
1064 event = extcon_get_state(cable->extcon_dev, in charger_manager_register_extcon()
1065 cable->extcon_type); in charger_manager_register_extcon()
1066 charger_extcon_notifier(&cable->nb, in charger_manager_register_extcon()
1081 return sprintf(buf, "%s\n", charger->regulator_name); in charger_name_show()
1091 if (!charger->externally_control) in charger_state_show()
1092 state = regulator_is_enabled(charger->consumer); in charger_state_show()
1103 return sprintf(buf, "%d\n", charger->externally_control); in charger_externally_control_show()
1113 struct charger_manager *cm = charger->cm; in charger_externally_control_store()
1114 struct charger_desc *desc = cm->desc; in charger_externally_control_store()
1122 ret = -EINVAL; in charger_externally_control_store()
1127 charger->externally_control = 0; in charger_externally_control_store()
1131 for (i = 0; i < desc->num_charger_regulators; i++) { in charger_externally_control_store()
1132 if (&desc->charger_regulators[i] != charger && in charger_externally_control_store()
1133 !desc->charger_regulators[i].externally_control) { in charger_externally_control_store()
1136 * charger-manager in charger_externally_control_store()
1144 if (cm->charger_enabled) { in charger_externally_control_store()
1145 try_charger_enable(charger->cm, false); in charger_externally_control_store()
1146 charger->externally_control = externally_control; in charger_externally_control_store()
1147 try_charger_enable(charger->cm, true); in charger_externally_control_store()
1149 charger->externally_control = externally_control; in charger_externally_control_store()
1152 dev_warn(cm->dev, in charger_externally_control_store()
1153 …"'%s' regulator should be controlled in charger-manager because charger-manager must need at least… in charger_externally_control_store()
1154 charger->regulator_name); in charger_externally_control_store()
1161 * charger_manager_prepare_sysfs - Prepare sysfs entry for each charger
1165 * user-space. If some development board use one more chargers for charging
1170 * externally_control, this charger isn't controlled from charger-manager and
1175 struct charger_desc *desc = cm->desc; in charger_manager_prepare_sysfs()
1182 for (i = 0; i < desc->num_charger_regulators; i++) { in charger_manager_prepare_sysfs()
1183 charger = &desc->charger_regulators[i]; in charger_manager_prepare_sysfs()
1185 name = devm_kasprintf(cm->dev, GFP_KERNEL, "charger.%d", i); in charger_manager_prepare_sysfs()
1187 return -ENOMEM; in charger_manager_prepare_sysfs()
1189 charger->attrs[0] = &charger->attr_name.attr; in charger_manager_prepare_sysfs()
1190 charger->attrs[1] = &charger->attr_state.attr; in charger_manager_prepare_sysfs()
1191 charger->attrs[2] = &charger->attr_externally_control.attr; in charger_manager_prepare_sysfs()
1192 charger->attrs[3] = NULL; in charger_manager_prepare_sysfs()
1194 charger->attr_grp.name = name; in charger_manager_prepare_sysfs()
1195 charger->attr_grp.attrs = charger->attrs; in charger_manager_prepare_sysfs()
1196 desc->sysfs_groups[i] = &charger->attr_grp; in charger_manager_prepare_sysfs()
1198 sysfs_attr_init(&charger->attr_name.attr); in charger_manager_prepare_sysfs()
1199 charger->attr_name.attr.name = "name"; in charger_manager_prepare_sysfs()
1200 charger->attr_name.attr.mode = 0444; in charger_manager_prepare_sysfs()
1201 charger->attr_name.show = charger_name_show; in charger_manager_prepare_sysfs()
1203 sysfs_attr_init(&charger->attr_state.attr); in charger_manager_prepare_sysfs()
1204 charger->attr_state.attr.name = "state"; in charger_manager_prepare_sysfs()
1205 charger->attr_state.attr.mode = 0444; in charger_manager_prepare_sysfs()
1206 charger->attr_state.show = charger_state_show; in charger_manager_prepare_sysfs()
1208 sysfs_attr_init(&charger->attr_externally_control.attr); in charger_manager_prepare_sysfs()
1209 charger->attr_externally_control.attr.name in charger_manager_prepare_sysfs()
1211 charger->attr_externally_control.attr.mode = 0644; in charger_manager_prepare_sysfs()
1212 charger->attr_externally_control.show in charger_manager_prepare_sysfs()
1214 charger->attr_externally_control.store in charger_manager_prepare_sysfs()
1217 if (!desc->charger_regulators[i].externally_control || in charger_manager_prepare_sysfs()
1221 dev_info(cm->dev, "'%s' regulator's externally_control is %d\n", in charger_manager_prepare_sysfs()
1222 charger->regulator_name, charger->externally_control); in charger_manager_prepare_sysfs()
1226 …dev_err(cm->dev, "Cannot register regulator because charger-manager must need at least one charger… in charger_manager_prepare_sysfs()
1227 return -EINVAL; in charger_manager_prepare_sysfs()
1238 struct charger_desc *desc = cm->desc; in cm_init_thermal_data()
1249 cm->desc->measure_battery_temp = true; in cm_init_thermal_data()
1252 if (ret && desc->thermal_zone) { in cm_init_thermal_data()
1253 cm->tzd_batt = in cm_init_thermal_data()
1254 thermal_zone_get_zone_by_name(desc->thermal_zone); in cm_init_thermal_data()
1255 if (IS_ERR(cm->tzd_batt)) in cm_init_thermal_data()
1256 return PTR_ERR(cm->tzd_batt); in cm_init_thermal_data()
1261 cm->desc->measure_battery_temp = true; in cm_init_thermal_data()
1265 if (cm->desc->measure_battery_temp) { in cm_init_thermal_data()
1267 if (!desc->temp_max) in cm_init_thermal_data()
1268 desc->temp_max = CM_DEFAULT_CHARGE_TEMP_MAX; in cm_init_thermal_data()
1269 if (!desc->temp_diff) in cm_init_thermal_data()
1270 desc->temp_diff = CM_DEFAULT_RECHARGE_TEMP_DIFF; in cm_init_thermal_data()
1278 .compatible = "charger-manager",
1286 struct device_node *np = dev->of_node; in of_cm_parse_desc()
1293 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1295 of_property_read_string(np, "cm-name", &desc->psy_name); in of_cm_parse_desc()
1297 of_property_read_u32(np, "cm-poll-mode", &poll_mode); in of_cm_parse_desc()
1298 desc->polling_mode = poll_mode; in of_cm_parse_desc()
1300 of_property_read_u32(np, "cm-poll-interval", in of_cm_parse_desc()
1301 &desc->polling_interval_ms); in of_cm_parse_desc()
1303 of_property_read_u32(np, "cm-fullbatt-vchkdrop-volt", in of_cm_parse_desc()
1304 &desc->fullbatt_vchkdrop_uV); in of_cm_parse_desc()
1305 of_property_read_u32(np, "cm-fullbatt-voltage", &desc->fullbatt_uV); in of_cm_parse_desc()
1306 of_property_read_u32(np, "cm-fullbatt-soc", &desc->fullbatt_soc); in of_cm_parse_desc()
1307 of_property_read_u32(np, "cm-fullbatt-capacity", in of_cm_parse_desc()
1308 &desc->fullbatt_full_capacity); in of_cm_parse_desc()
1310 of_property_read_u32(np, "cm-battery-stat", &battery_stat); in of_cm_parse_desc()
1311 desc->battery_present = battery_stat; in of_cm_parse_desc()
1314 num_chgs = of_property_count_strings(np, "cm-chargers"); in of_cm_parse_desc()
1319 desc->psy_charger_stat = devm_kcalloc(dev, in of_cm_parse_desc()
1323 if (!desc->psy_charger_stat) in of_cm_parse_desc()
1324 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1327 of_property_read_string_index(np, "cm-chargers", in of_cm_parse_desc()
1328 i, &desc->psy_charger_stat[i]); in of_cm_parse_desc()
1331 of_property_read_string(np, "cm-fuel-gauge", &desc->psy_fuel_gauge); in of_cm_parse_desc()
1333 of_property_read_string(np, "cm-thermal-zone", &desc->thermal_zone); in of_cm_parse_desc()
1335 of_property_read_u32(np, "cm-battery-cold", &desc->temp_min); in of_cm_parse_desc()
1336 if (of_get_property(np, "cm-battery-cold-in-minus", NULL)) in of_cm_parse_desc()
1337 desc->temp_min *= -1; in of_cm_parse_desc()
1338 of_property_read_u32(np, "cm-battery-hot", &desc->temp_max); in of_cm_parse_desc()
1339 of_property_read_u32(np, "cm-battery-temp-diff", &desc->temp_diff); in of_cm_parse_desc()
1341 of_property_read_u32(np, "cm-charging-max", in of_cm_parse_desc()
1342 &desc->charging_max_duration_ms); in of_cm_parse_desc()
1343 of_property_read_u32(np, "cm-discharging-max", in of_cm_parse_desc()
1344 &desc->discharging_max_duration_ms); in of_cm_parse_desc()
1347 desc->num_charger_regulators = of_get_child_count(np); in of_cm_parse_desc()
1348 if (desc->num_charger_regulators) { in of_cm_parse_desc()
1353 desc->num_charger_regulators, in of_cm_parse_desc()
1357 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1359 desc->charger_regulators = chg_regs; in of_cm_parse_desc()
1361 desc->sysfs_groups = devm_kcalloc(dev, in of_cm_parse_desc()
1362 desc->num_charger_regulators + 1, in of_cm_parse_desc()
1363 sizeof(*desc->sysfs_groups), in of_cm_parse_desc()
1365 if (!desc->sysfs_groups) in of_cm_parse_desc()
1366 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1372 of_property_read_string(child, "cm-regulator-name", in of_cm_parse_desc()
1373 &chg_regs->regulator_name); in of_cm_parse_desc()
1376 chg_regs->num_cables = of_get_child_count(child); in of_cm_parse_desc()
1377 if (chg_regs->num_cables) { in of_cm_parse_desc()
1379 chg_regs->num_cables, in of_cm_parse_desc()
1384 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1387 chg_regs->cables = cables; in of_cm_parse_desc()
1391 "cm-cable-name", &cables->name); in of_cm_parse_desc()
1393 "cm-cable-extcon", in of_cm_parse_desc()
1394 &cables->extcon_name); in of_cm_parse_desc()
1396 "cm-cable-min", in of_cm_parse_desc()
1397 &cables->min_uA); in of_cm_parse_desc()
1399 "cm-cable-max", in of_cm_parse_desc()
1400 &cables->max_uA); in of_cm_parse_desc()
1412 if (pdev->dev.of_node) in cm_get_drv_data()
1413 return of_cm_parse_desc(&pdev->dev); in cm_get_drv_data()
1414 return dev_get_platdata(&pdev->dev); in cm_get_drv_data()
1435 dev_err(&pdev->dev, "No platform data (desc) found\n"); in charger_manager_probe()
1439 cm = devm_kzalloc(&pdev->dev, sizeof(*cm), GFP_KERNEL); in charger_manager_probe()
1441 return -ENOMEM; in charger_manager_probe()
1444 cm->dev = &pdev->dev; in charger_manager_probe()
1445 cm->desc = desc; in charger_manager_probe()
1450 cm_timer = devm_kzalloc(cm->dev, sizeof(*cm_timer), GFP_KERNEL); in charger_manager_probe()
1452 return -ENOMEM; in charger_manager_probe()
1460 if (desc->fullbatt_uV == 0) { in charger_manager_probe()
1461 dev_info(&pdev->dev, "Ignoring full-battery voltage threshold as it is not supplied\n"); in charger_manager_probe()
1463 if (!desc->fullbatt_vchkdrop_uV) { in charger_manager_probe()
1464 …dev_info(&pdev->dev, "Disabling full-battery voltage drop checking mechanism as it is not supplied… in charger_manager_probe()
1465 desc->fullbatt_vchkdrop_uV = 0; in charger_manager_probe()
1467 if (desc->fullbatt_soc == 0) { in charger_manager_probe()
1468 …dev_info(&pdev->dev, "Ignoring full-battery soc(state of charge) threshold as it is not supplied\n… in charger_manager_probe()
1470 if (desc->fullbatt_full_capacity == 0) { in charger_manager_probe()
1471 dev_info(&pdev->dev, "Ignoring full-battery full capacity threshold as it is not supplied\n"); in charger_manager_probe()
1474 if (!desc->charger_regulators || desc->num_charger_regulators < 1) { in charger_manager_probe()
1475 dev_err(&pdev->dev, "charger_regulators undefined\n"); in charger_manager_probe()
1476 return -EINVAL; in charger_manager_probe()
1479 if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) { in charger_manager_probe()
1480 dev_err(&pdev->dev, "No power supply defined\n"); in charger_manager_probe()
1481 return -EINVAL; in charger_manager_probe()
1484 if (!desc->psy_fuel_gauge) { in charger_manager_probe()
1485 dev_err(&pdev->dev, "No fuel gauge power supply defined\n"); in charger_manager_probe()
1486 return -EINVAL; in charger_manager_probe()
1490 for (i = 0; desc->psy_charger_stat[i]; i++) { in charger_manager_probe()
1493 psy = power_supply_get_by_name(desc->psy_charger_stat[i]); in charger_manager_probe()
1495 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", in charger_manager_probe()
1496 desc->psy_charger_stat[i]); in charger_manager_probe()
1497 return -ENODEV; in charger_manager_probe()
1502 if (cm->desc->polling_mode != CM_POLL_DISABLE && in charger_manager_probe()
1503 (desc->polling_interval_ms == 0 || in charger_manager_probe()
1504 msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL)) { in charger_manager_probe()
1505 dev_err(&pdev->dev, "polling_interval_ms is too small\n"); in charger_manager_probe()
1506 return -EINVAL; in charger_manager_probe()
1509 if (!desc->charging_max_duration_ms || in charger_manager_probe()
1510 !desc->discharging_max_duration_ms) { in charger_manager_probe()
1511 …dev_info(&pdev->dev, "Cannot limit charging duration checking mechanism to prevent overcharge/over… in charger_manager_probe()
1512 desc->charging_max_duration_ms = 0; in charger_manager_probe()
1513 desc->discharging_max_duration_ms = 0; in charger_manager_probe()
1518 memcpy(&cm->charger_psy_desc, &psy_default, sizeof(psy_default)); in charger_manager_probe()
1520 if (!desc->psy_name) in charger_manager_probe()
1521 strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); in charger_manager_probe()
1523 strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); in charger_manager_probe()
1524 cm->charger_psy_desc.name = cm->psy_name_buf; in charger_manager_probe()
1527 properties = devm_kcalloc(&pdev->dev, in charger_manager_probe()
1532 return -ENOMEM; in charger_manager_probe()
1539 /* Find which optional psy-properties are available */ in charger_manager_probe()
1540 fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); in charger_manager_probe()
1542 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", in charger_manager_probe()
1543 desc->psy_fuel_gauge); in charger_manager_probe()
1544 return -ENODEV; in charger_manager_probe()
1568 dev_err(&pdev->dev, "Failed to initialize thermal data\n"); in charger_manager_probe()
1569 cm->desc->measure_battery_temp = false; in charger_manager_probe()
1573 cm->charger_psy_desc.properties = properties; in charger_manager_probe()
1574 cm->charger_psy_desc.num_properties = num_properties; in charger_manager_probe()
1579 dev_err(&pdev->dev, in charger_manager_probe()
1583 psy_cfg.attr_grp = desc->sysfs_groups; in charger_manager_probe()
1585 cm->charger_psy = power_supply_register(&pdev->dev, in charger_manager_probe()
1586 &cm->charger_psy_desc, in charger_manager_probe()
1588 if (IS_ERR(cm->charger_psy)) { in charger_manager_probe()
1589 dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n", in charger_manager_probe()
1590 cm->charger_psy_desc.name); in charger_manager_probe()
1591 return PTR_ERR(cm->charger_psy); in charger_manager_probe()
1597 dev_err(&pdev->dev, "Cannot initialize extcon device\n"); in charger_manager_probe()
1603 list_add(&cm->entry, &cm_list); in charger_manager_probe()
1607 * Charger-manager is capable of waking up the systme from sleep in charger_manager_probe()
1610 device_init_wakeup(&pdev->dev, true); in charger_manager_probe()
1611 device_set_wakeup_capable(&pdev->dev, false); in charger_manager_probe()
1614 * Charger-manager have to check the charging state right after in charger_manager_probe()
1615 * initialization of charger-manager and then update current charging in charger_manager_probe()
1625 for (i = 0; i < desc->num_charger_regulators; i++) in charger_manager_probe()
1626 regulator_put(desc->charger_regulators[i].consumer); in charger_manager_probe()
1628 power_supply_unregister(cm->charger_psy); in charger_manager_probe()
1636 struct charger_desc *desc = cm->desc; in charger_manager_remove()
1641 list_del(&cm->entry); in charger_manager_remove()
1647 for (i = 0 ; i < desc->num_charger_regulators ; i++) in charger_manager_remove()
1648 regulator_put(desc->charger_regulators[i].consumer); in charger_manager_remove()
1650 power_supply_unregister(cm->charger_psy); in charger_manager_remove()
1658 { "charger-manager", 0 },
1667 return -EAGAIN; in cm_suspend_noirq()
1695 return -EBUSY; in cm_suspend_prepare()
1723 cm_suspend_duration_ms -= ktime_to_ms(remain); in cm_suspend_complete()
1729 device_set_wakeup_capable(cm->dev, false); in cm_suspend_complete()
1740 .name = "charger-manager",
1753 return -ENOMEM; in charger_manager_init()