/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
structmtk_batterygm; voidmtk_battery_init(structplatform_device*dev) { gm.log_level=BM_DAEMON_DEFAULT_LOG_LEVEL; gm.d_log_level=BM_DAEMON_DEFAULT_LOG_LEVEL; ...... init_waitqueue_head(&gm.wait_que);//wait_queue_head_twait_que; ...... gm.gdev=get_gauge_by_name("gauge"); fg_custom_init_from_dts(dev);//kernel-4.14/arch/arm64/boot/dts/mediatek/bat_setting/tb8168_battery_prop_ext.dtsi ...... kthread_run(battery_update_routine,NULL,"battery_thread"); fg_drv_thread_hrtimer_init(); alarm_init(&gm.tracking_timer,ALARM_BOOTTIME,tracking_timer_callback); alarm_init(&gm.one_percent_timer,ALARM_BOOTTIME,one_percent_timer_callback); mtk_power_misc_init(dev);//这又开了一个"power_misc_thread"线程,处理异常状态(温度过高,电量过低)(这很重要,下次分解) ->kthread_run(power_misc_routine_thread, &sdc, "power_misc_thread"); ...... } |
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
intbattery_update_routine(void*x) { battery_update_psd(&battery_main); while(1){ wait_event(gm.wait_que,(gm.fg_update_flag>0)||(gm.tracking_cb_flag>0)||(gm.onepercent_cb_flag>0)); if(gm.fg_update_flag>0){ gm.fg_update_flag=0; fg_drv_update_hw_status(); } if(gm.tracking_cb_flag>0){ bm_err("%swakebytracking_cb_flag:%d\n",__func__,gm.tracking_cb_flag); gm.tracking_cb_flag=0; wakeup_fg_algo(FG_INTR_FG_TIME); } if(gm.onepercent_cb_flag>0){ bm_err("%swakebyonepercent_cb_flag:%d\n",__func__,gm.onepercent_cb_flag); nbsp; gm.onepercent_cb_flag = 0; wakeup_fg_algo_cmd(FG_INTR_FG_TIME, 0, 1); } if (gm.fix_coverity == 1) return 0; } } void fg_update_routine_wakeup(void) { gm.fg_update_flag = 1; wake_up(&gm.wait_que); } enum hrtimer_restart fg_drv_thread_hrtimer_func(struct hrtimer *timer) { fg_update_routine_wakeup(); return HRTIMER_NORESTART; } void fg_drv_thread_hrtimer_init(void) { ktime_t ktime = ktime_set(10, 0); //10s hrtimer_init(&gm.fg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); gm.fg_hrtimer.function = fg_drv_thread_hrtimer_func; hrtimer_start(&gm.fg_hrtimer, ktime, HRTIMER_MODE_REL); } |
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/* ============================================================ */ /* periodic */ /* ============================================================ */ void fg_drv_update_hw_status(void) { static bool fg_current_state; signed int chr_vol; int fg_current, fg_coulomb, bat_vol; int plugout_status, tmp, bat_plugout_time; int fg_current_iavg; bool valid = false; static unsigned int cnt; ktime_t ktime = ktime_set(60, 0); bm_debug("[%s]=>\n", __func__); if (gauge_get_hw_version() >= GAUGE_HW_V1000 && gauge_get_hw_version() < GAUGE_HW_V2000) fg_int_event(gm.gdev, EVB_PERIODIC_CHECK); fg_update_sw_iavg(); gauge_dev_get_boot_battery_plug_out_status( gm.gdev, &plugout_status, &bat_plugout_time); fg_current_state = gauge_get_current(&fg_current); fg_coulomb = gauge_get_coulomb(); bat_vol = pmic_get_battery_voltage(); chr_vol = battery_get_vbus(); tmp = force_get_tbat(true); bm_err("lbat %d %d %d %d\n", gm.sw_low_battery_ht_en, gm.sw_low_battery_ht_threshold, gm.sw_low_battery_lt_en, gm.sw_low_battery_lt_threshold); bm_err("car[%d,%ld,%ld,%ld,%ld, cycle_car:%d,ncar:%d] c:%d %d vbat:%d vbus:%d soc:%d %d gm3:%d %d %d %d\n", fg_coulomb, gm.coulomb_plus.end, gm.coulomb_minus.end, gm.soc_plus.end, gm.soc_minus.end, gm.bat_cycle_car, gm.bat_cycle_ncar, fg_current_state, fg_current, bat_vol, chr_vol, battery_get_soc(), battery_get_uisoc(), gm.disableGM30, fg_cust_data.disable_nafg, gm.ntc_disable_nafg, gm.cmd_disable_nafg); if (bat_get_debug_level() >= 7) gauge_coulomb_dump_list(); fg_current_iavg = gauge_get_average_current(&valid); fg_nafg_monitor(); bm_err("tmp:%d %d %d hcar2:%d lcar2:%d time:%d sw_iavg:%d %d %d nafg_m:%d %d %d\n", tmp, gm.fg_bat_tmp_int_ht, gm.fg_bat_tmp_int_lt, gm.fg_bat_int2_ht, gm.fg_bat_int2_lt, fg_get_system_sec(), gm.sw_iavg, fg_current_iavg, valid, gm.last_nafg_cnt, gm.is_nafg_broken, gm.disable_nafg_int); if (cnt % 10 == 0) gauge_dev_dump(gm.gdev, NULL, 0); cnt++; gm3_log_dump(false); gm3_log_dump_nafg(1); wakeup_fg_algo_cmd( FG_INTR_KERNEL_CMD, FG_KERNEL_CMD_DUMP_REGULAR_LOG, 0); if (bat_get_debug_level() >= ) ktime = ktime_set(10, 0); else ktime = ktime_set(60, 0); hrtimer_start(&gm.fg_hrtimer, ktime, HRTIMER_MODE_REL); } |
gm.log_level在mtk_battery_init()被初始化为3,所以ktime被设置为60s
(我觉得这里逻辑有问题),因为log数字越小,等级越高,所以应该写成:
if (bat_get_debug_level() < ) ktime = ktime_set(10, 0); //log_level小于7,说明等级高,从而应该更频繁地打印log else ktime = ktime_set(60, 0);
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery.c
1 2 3 4 |
int bat_get_debug_level(void) { return gm.log_level; } |
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_internal.h
1 2 3 4 5 6 7 8 9 10 11 |
/* ============================================================ */ /* typedef and Struct*/ /* ============================================================ */ #define BMLOG_ERROR_LEVEL 3 #define BMLOG_WARNING_LEVEL 4 #define BMLOG_NOTICE_LEVEL 5 #define BMLOG_INFO_LEVEL 6 #define 7 #define BMLOG_TRACE_LEVEL 8 #define 3 |
另外,以下两个定时器也可以唤醒线程battery_update_routine:
/kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery_core.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/* ============================================================ */ /* alarm timer handler */ /* ============================================================ */ static enum alarmtimer_restart tracking_timer_callback( struct alarm *alarm, ktime_t now) { gm.tracking_cb_flag = 1; wake_up(&gm.wait_que); return ALARMTIMER_NORESTART; } static enum alarmtimer_restart one_percent_timer_callback( struct alarm *alarm, ktime_t now) { gm.onepercent_cb_flag = 1; wake_up(&gm.wait_que); return ALARMTIMER_NORESTART; } void bmd_ctrl_cmd_from_user(void *nl_data, struct fgd_nl_msg_t *ret_msg) { ... ... case FG_DAEMON_CMD_SET_FG_TIME: { int secs; struct timespec time, time_now, end_time; ktime_t ktime; memcpy(&secs, &msg->fgd_data[0], sizeof(secs)); if (secs != 0 && secs > 0) { get_monotonic_boottime(&time_now); time.tv_sec = secs; time.tv_nsec = 0; end_time = timespec_add(time_now, time); ktime = ktime_set(end_time.tv_sec, end_time.tv_nsec); if (msg->fgd_subcmd_para1 == 0) alarm_start(&gm.tracking_timer, ktime); else alarm_start(&gm.one_percent_timer, ktime); } else { if (msg->fgd_subcmd_para1 == 0) alarm_cancel(&gm.tracking_timer); else alarm_cancel(&gm.one_percent_timer); } bm_err("[fr] FG_DAEMON_CMD_SET_FG_TIME = %d cmd:%d %d\n", secs, msg->fgd_subcmd, msg->fgd_subcmd_para1); } break; ... ... } |