power: rk81x-battery: support otg device
[firefly-linux-kernel-4.4.55.git] / drivers / power / rk818_battery.c
old mode 100755 (executable)
new mode 100644 (file)
index b28a1e6..5f2d4c4
@@ -53,6 +53,8 @@
 
 #if defined(CONFIG_X86_INTEL_SOFIA)
 #include <linux/usb/phy-intel.h>
+#else
+#include <linux/power/rk_usbbc.h>
 #endif
 #include "rk818_battery.h"
 
@@ -149,6 +151,10 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
 #define DSOC_CHRG_FINISH_CURR  1100
 #define SLP_CHRG_CURR          1000
 #define SLP_DSOC_VOL_THRESD    3600
+/*if voltage is lower than this thresd,
+   we consider it as invalid
+ */
+#define INVALID_VOL_THRESD     2500
 #define PWR_OFF_THRESD         3400
 #define MIN_ZERO_ACCURACY      10      /*0.01%*/
 
@@ -173,7 +179,6 @@ u8 CHRG_CVCC_HOUR[] = {4, 5, 6, 8, 10, 12, 14, 16};
 #define        OCV_VALID_SHIFT         (0)
 #define        OCV_CALIB_SHIFT         (1)
 #define FIRST_PWRON_SHIFT      (2)
-#define LOADER_CHRG_SHIFT      (3)
 
 #define SEC_TO_MIN(x)          ((x) / 60)
 
@@ -286,7 +291,7 @@ struct rk81x_battery {
        struct delayed_work             charge_check_work;
        struct delayed_work             usb_phy_delay_work;
        struct delayed_work             chrg_term_mode_switch_work;
-       int                             charge_otg;
+       enum bc_port_type               charge_otg;
        int                             ma;
 
        struct wake_lock                resume_wake_lock;
@@ -596,7 +601,7 @@ static void rk81x_bat_capacity_init(struct rk81x_battery *di, u32 capacity)
 
        } while (buf == 0);
 
-       dev_info(di->dev, "update capacity :%d--remain_cap:%d\n",
+       dev_dbg(di->dev, "update capacity :%d--remain_cap:%d\n",
                 capacity, di->remain_capacity);
 }
 
@@ -921,7 +926,7 @@ static uint16_t rk81x_bat_get_ocv_vol(struct rk81x_battery *di)
 static int rk81x_bat_get_vol(struct rk81x_battery *di)
 {
        int ret;
-       int voltage_now = 0;
+       int vol;
        u8 buf;
        int temp;
        int val[3];
@@ -944,9 +949,9 @@ static int rk81x_bat_get_vol(struct rk81x_battery *di)
        else
                temp = val[2];
 
-       voltage_now = di->voltage_k * temp / 1000 + di->voltage_b;
+       vol = di->voltage_k * temp / 1000 + di->voltage_b;
 
-       return voltage_now;
+       return vol;
 }
 
 static bool is_rk81x_bat_relax_mode(struct rk81x_battery *di)
@@ -1087,7 +1092,7 @@ static bool rk81x_bat_zero_current_calib(struct rk81x_battery *di)
        int ioffset;
        u8 pcb_offset = 0;
        u8 retry = 0;
-       bool ret;
+       bool ret = true;
 
        if ((di->chrg_status == CHARGE_FINISH) &&
            (BASE_TO_MIN(di->power_on_base) >= 3) &&
@@ -1095,7 +1100,7 @@ static bool rk81x_bat_zero_current_calib(struct rk81x_battery *di)
                for (retry = 0; retry < 5; retry++) {
                        adc_value = rk81x_bat_get_raw_adc_current(di);
                        if (!rk81x_chrg_online(di) || abs(adc_value) > 30) {
-                               dev_dbg(di->dev, "charger plugout\n");
+                               dev_warn(di->dev, "charger plugout\n");
                                ret = true;
                                break;
                        }
@@ -1131,7 +1136,7 @@ static bool rk81x_bat_zero_current_calib(struct rk81x_battery *di)
                                ret = false;
                                break;
                        } else {
-                               dev_warn(di->dev, "ioffset cal failed\n");
+                               dev_dbg(di->dev, "ioffset cal failed\n");
                                rk81x_bat_set_cal_offset(di, C0);
                        }
 
@@ -1705,15 +1710,6 @@ static int rk81x_bat_save_reboot_cnt(struct  rk81x_battery *di, u8 save_cnt)
        return 0;
 }
 
-static u8 rk81x_bat_support_loader_chrg(struct rk81x_battery *di)
-{
-       u8 ret;
-
-       ret = rk81x_bat_read_bit(di, MISC_MARK_REG, LOADER_CHRG_SHIFT);
-       rk81x_bat_clr_bit(di, MISC_MARK_REG, LOADER_CHRG_SHIFT);
-       return ret;
-}
-
 static void rk81x_bat_set_current(struct rk81x_battery *di, int charge_current)
 {
        u8 usb_ctrl_reg;
@@ -1792,7 +1788,7 @@ static enum charger_type rk81x_bat_get_dc_state(struct rk81x_battery *di)
        /*HW_ADP_TYPE_DUAL: det by rk818 and usb*/
        } else if (rk81x_bat_support_adp_type(HW_ADP_TYPE_DUAL)) {
                if ((buf & PLUG_IN_STS) != 0) {
-                       charger_type = dwc_otg_check_dpdm();
+                       charger_type = dwc_otg_check_dpdm(0);
                        if (charger_type == 0)
                                charger_type = DC_CHARGER;
                        else
@@ -1808,7 +1804,7 @@ static enum charger_type rk81x_bat_get_usbac_state(struct rk81x_battery *di)
        enum charger_type charger_type;
        int usb_id, gadget_flag;
 
-       usb_id = dwc_otg_check_dpdm();
+       usb_id = dwc_otg_check_dpdm(0);
        switch (usb_id) {
        case 0:
                charger_type = NO_CHARGER;
@@ -2061,9 +2057,10 @@ static void rk81x_bat_not_first_pwron(struct rk81x_battery *di)
         * if support, uboot charge driver should have done init work,
         * so here we should skip init work
         */
-       if (rk81x_bat_support_loader_chrg(di))
+#if defined(CONFIG_ARCH_ROCKCHIP)
+       if (di->loader_charged)
                goto out;
-
+#endif
        calib_vol = rk81x_bat_get_calib_vol(di);
        if (calib_vol > 0) {
                calib_soc = rk81x_bat_vol_to_capacity(di, calib_vol);
@@ -2259,7 +2256,7 @@ static u8 rk81x_bat_select_finish_ma(int fcc)
 
        return ma;
 }
-
+#if 0
 /*
  * there is a timer inside rk81x to calc how long the battery is in charging
  * state. rk81x will close PowerPath inside IC when timer reach, which will
@@ -2279,6 +2276,7 @@ static void rk81x_bat_init_chrg_timer(struct rk81x_battery *di)
        rk81x_bat_write(di, CHRG_CTRL_REG3, &buf, 1);
        dev_info(di->dev, "reset cccv charge timer\n");
 }
+#endif
 
 static void rk81x_bat_charger_init(struct  rk81x_battery *di)
 {
@@ -2294,7 +2292,7 @@ static void rk81x_bat_charger_init(struct  rk81x_battery *di)
        rk81x_bat_match_param(di, chrg_vol, chrg_ilim, chrg_cur);
        finish_ma = rk81x_bat_select_finish_ma(di->fcc);
 
-       rk81x_bat_init_chrg_timer(di);
+       /*rk81x_bat_init_chrg_timer(di);*/
 
        rk81x_bat_read(di, THERMAL_REG, &thremal_reg, 1);
        rk81x_bat_read(di, USB_CTRL_REG, &usb_ctrl_reg, 1);
@@ -2318,6 +2316,8 @@ static void rk81x_bat_charger_init(struct  rk81x_battery *di)
        chrg_ctrl_reg1 |= (CHRG_EN) | (di->chrg_v_lmt | di->chrg_i_cur);
 
        chrg_ctrl_reg3 |= CHRG_TERM_DIG_SIGNAL;/* digital finish mode*/
+       chrg_ctrl_reg3 &= ~CHRG_TIMER_CCCV_EN;/*disable*/
+
        chrg_ctrl_reg2 &= ~(0xc7);
        chrg_ctrl_reg2 |= finish_ma | CHG_CCCV_6HOUR;
 
@@ -2341,16 +2341,23 @@ static void rk81x_bat_charger_init(struct  rk81x_battery *di)
 
 void rk81x_charge_disable_open_otg(struct rk81x_battery *di)
 {
-       int value = di->charge_otg;
+       enum bc_port_type event = di->charge_otg;
 
-       if (value) {
+       switch (event) {
+       case USB_OTG_POWER_ON:
                DBG("charge disable, enable OTG.\n");
                rk818_set_bits(di->rk818, CHRG_CTRL_REG1, 1 << 7, 0 << 7);
                rk818_set_bits(di->rk818, 0x23, 1 << 7, 1 << 7);
-       } else {
+               break;
+
+       case USB_OTG_POWER_OFF:
                DBG("charge enable, disable OTG.\n");
                rk818_set_bits(di->rk818, 0x23, 1 << 7, 0 << 7);
                rk818_set_bits(di->rk818, CHRG_CTRL_REG1, 1 << 7, 1 << 7);
+               break;
+
+       default:
+               break;
        }
 }
 
@@ -2362,9 +2369,6 @@ static void rk81x_bat_fg_init(struct rk81x_battery *di)
 
        val = 0x30;
        rk81x_bat_write(di, ADC_CTRL_REG, &val, 1);
-       rk81x_bat_read(di, RK818_VB_MON_REG, &val, 1);
-       if (val & PLUG_IN_STS)
-               rk81x_bat_set_power_supply_state(di, USB_CHARGER);
 
        rk81x_bat_gauge_enable(di);
        /* get the volatege offset */
@@ -2419,7 +2423,8 @@ static void rk81x_bat_zero_calc_linek(struct rk81x_battery *di)
        int voltage, voltage_old, voltage_now;
        int i, rsoc;
        int q_ocv, q_dead;
-       int count_num, currentnow;
+       int count_num = 0;
+       int currentnow;
        int ocv_soc, dead_soc;
        int power_off_thresd = di->pdata->power_off_thresd;
 
@@ -2461,7 +2466,7 @@ static void rk81x_bat_zero_calc_linek(struct rk81x_battery *di)
        rsoc = ocv_soc - dead_soc;
        if ((di->dsoc == 1) && (rsoc > 0)) {/*discharge*/
                di->line_k = 1000;
-       } else if (rsoc > 1) {
+       } else if (rsoc > 0) {
                di->line_k = (di->display_soc + rsoc / 2) / div(rsoc);
        } else {
                di->dsoc--;
@@ -2592,7 +2597,7 @@ static void rk81x_bat_rsoc_check(struct rk81x_battery *di)
 
 static void rk81x_bat_emulator_dischrg(struct rk81x_battery *di)
 {
-       u32 temp, soc_time;
+       u32 temp, soc_time = 0;
        unsigned long sec_unit;
 
        if (!di->dischrg_emu_base)
@@ -2623,7 +2628,7 @@ static void rk81x_bat_emulator_dischrg(struct rk81x_battery *di)
  */
 static void rk81x_bat_emulator_chrg(struct rk81x_battery *di)
 {
-       u32 soc_time, temp;
+       u32 soc_time = 0, temp;
        int plus_soc;
        unsigned long chrg_emu_sec;
 
@@ -2954,7 +2959,7 @@ static void rk81x_bat_wait_finish_sig(struct rk81x_battery *di)
 static void rk81x_bat_finish_chrg(struct rk81x_battery *di)
 {
        unsigned long sec_finish;
-       int soc_time, plus_soc;
+       int soc_time = 0, plus_soc;
        int temp;
 
        if (di->dsoc < 100) {
@@ -2966,7 +2971,7 @@ static void rk81x_bat_finish_chrg(struct rk81x_battery *di)
                temp = di->fcc * 3600 / 100;
                if (di->ac_online)
                        soc_time = temp / DSOC_CHRG_FINISH_CURR;
-               else if (di->usb_online)
+               else
                        soc_time = temp / 450;
 
                plus_soc = sec_finish / soc_time;
@@ -3154,11 +3159,9 @@ static void rk81x_bat_chrg_smooth(struct rk81x_battery *di)
 {
        u32 *ocv_table = di->pdata->battery_ocv;
        int delta_soc = di->rsoc - di->dsoc;
-       int chrg_finish_vol = di->pdata->max_charger_voltagemV;
 
-       if ((di->chrg_status == CHARGE_FINISH ||
-            di->slp_chrg_status == CHARGE_FINISH) &&
-            (di->voltage > chrg_finish_vol - 150)) {
+       if (di->chrg_status == CHARGE_FINISH ||
+           di->slp_chrg_status == CHARGE_FINISH) {
                /*clear sleep charge status*/
                di->slp_chrg_status = rk81x_bat_get_chrg_status(di);
                di->chrg_emu_base = 0;
@@ -3168,8 +3171,8 @@ static void rk81x_bat_chrg_smooth(struct rk81x_battery *di)
                rk81x_bat_capacity_init(di, di->fcc);
                rk81x_bat_capacity_init_post(di);
        } else if ((di->ac_online == ONLINE && di->dsoc >= 90) &&
-           ((di->current_avg > DSOC_CHRG_TERM_CURR) ||
-            (di->voltage < ocv_table[18] + 20))) {
+                  ((di->current_avg > DSOC_CHRG_TERM_CURR) ||
+                   (di->voltage < ocv_table[18] + 20))) {
                di->chrg_emu_base = 0;
                di->chrg_normal_base = 0;
                di->chrg_finish_base = 0;
@@ -3302,7 +3305,8 @@ static void rk81x_bat_vol_calib(struct rk81x_battery *di, int condition)
 
 static int  rk81x_bat_sleep_dischrg(struct rk81x_battery *di)
 {
-       int delta_soc, temp_dsoc;
+       int delta_soc = 0;
+       int temp_dsoc;
        unsigned long sleep_sec = di->suspend_time_sum;
        int power_off_thresd = di->pdata->power_off_thresd;
 
@@ -3379,7 +3383,7 @@ static int  rk81x_bat_sleep_dischrg(struct rk81x_battery *di)
 
 static int rk81x_bat_sleep_chrg(struct rk81x_battery *di)
 {
-       int sleep_soc;
+       int sleep_soc = 0;
        unsigned long sleep_sec;
 
        sleep_sec = di->suspend_time_sum;
@@ -3427,8 +3431,12 @@ static void rk81x_bat_power_supply_changed(struct rk81x_battery *di)
        else if (old_charge_status != di->psy_status)
                state_changed = true;
 
-       if (di->dsoc >= 100 && rk81x_chrg_online(di))
-               di->psy_status = POWER_SUPPLY_STATUS_FULL;
+       if (rk81x_chrg_online(di)) {
+               if (di->dsoc == 100)
+                       di->psy_status = POWER_SUPPLY_STATUS_FULL;
+               else
+                       di->psy_status = POWER_SUPPLY_STATUS_CHARGING;
+       }
 
        if (state_changed) {
                power_supply_changed(&di->bat);
@@ -3443,6 +3451,7 @@ static void rk81x_bat_power_supply_changed(struct rk81x_battery *di)
        }
 }
 
+#if 0
 static u8 rk81x_bat_get_cvcc_chrg_hour(struct rk81x_battery *di)
 {
        u8 hour, buf;
@@ -3483,12 +3492,13 @@ static void rk81x_bat_chrg_over_time_check(struct rk81x_battery *di)
                    di->current_avg);
 
                if (SEC_TO_MIN(di->chrg_time2full) > 60) {
-                       rk81x_bat_init_chrg_timer(di);
+                       /*rk81x_bat_init_chrg_timer(di);*/
                        di->plug_in_base = get_runtime_sec();
                        DBG("%s: reset charge timer\n", __func__);
                }
        }
 }
+#endif
 
 /*
  * in case that we will do reboot stress test, we need a special way
@@ -3498,7 +3508,6 @@ static void rk81x_bat_check_reboot(struct rk81x_battery *di)
 {
        u8 rsoc = di->rsoc;
        u8 dsoc = di->dsoc;
-       u8 status = di->psy_status;
        u8 cnt;
        int unit_time;
        int smooth_time;
@@ -3513,9 +3522,7 @@ static void rk81x_bat_check_reboot(struct rk81x_battery *di)
            __func__, cnt, unit_time, smooth_time,
            BASE_TO_SEC(di->power_on_base), dsoc, rsoc);
 
-       if (((status == POWER_SUPPLY_STATUS_CHARGING) ||
-            (status == POWER_SUPPLY_STATUS_FULL)) &&
-            (abs(di->current_avg) < 5)) {
+       if (di->current_avg >= 0 || di->chrg_status == CHARGE_FINISH) {
                DBG("chrg, sm:%d, aim:%d\n", smooth_time, unit_time * 3 / 5);
                if ((dsoc < rsoc - 1) && (smooth_time > unit_time * 3 / 5)) {
                        cnt = 0;
@@ -3524,10 +3531,9 @@ static void rk81x_bat_check_reboot(struct rk81x_battery *di)
                                dsoc = 100;
                        rk81x_bat_save_dsoc(di, dsoc);
                }
-       } else {/*status == POWER_SUPPLY_STATUS_DISCHARGING*/
-
-               DBG("dischrg, sm:%d, aim:%d\n", smooth_time, unit_time * 3/5);
-               if ((dsoc > rsoc) && (smooth_time > unit_time * 3/5)) {
+       } else {
+               DBG("dischrg, sm:%d, aim:%d\n", smooth_time, unit_time * 3 / 5);
+               if ((dsoc > rsoc) && (smooth_time > unit_time * 3 / 5)) {
                        cnt = 0;
                        dsoc--;
                        if (dsoc <= 0)
@@ -3587,7 +3593,7 @@ static void rk81x_bat_update_info(struct rk81x_battery *di)
        di->relax_voltage = rk81x_bat_get_relax_vol(di);
        di->est_ocv_vol = rk81x_bat_est_ocv_vol(di);
        di->est_ocv_soc = rk81x_bat_est_ocv_soc(di);
-       rk81x_bat_chrg_over_time_check(di);
+       /*rk81x_bat_chrg_over_time_check(di);*/
        rk81x_bat_update_calib_param(di);
        if (di->chrg_status == CC_OR_CV)
                di->enter_finish = true;
@@ -3753,17 +3759,6 @@ int battery_notifier_call_chain(unsigned long val)
 }
 EXPORT_SYMBOL_GPL(battery_notifier_call_chain);
 
-static void poweron_lowerpoer_handle(struct rk81x_battery *di)
-{
-#ifdef CONFIG_LOGO_LOWERPOWER_WARNING
-       if ((di->dsoc <= 2) &&
-           (di->psy_status == POWER_SUPPLY_STATUS_DISCHARGING)) {
-               mdelay(1500);
-               /* kernel_power_off(); */
-       }
-#endif
-}
-
 static int rk81x_bat_notifier_call(struct notifier_block *nb,
                                   unsigned long event, void *data)
 {
@@ -3771,24 +3766,22 @@ static int rk81x_bat_notifier_call(struct notifier_block *nb,
            container_of(nb, struct rk81x_battery, battery_nb);
 
        switch (event) {
-       case 0:
-               DBG(" CHARGE enable\n");
-               di->charge_otg = 0;
-               rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_IN_INT);
-               rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_OUT_INT);
-               queue_delayed_work(di->wq, &di->charge_check_work,
-                                  msecs_to_jiffies(50));
-               break;
-       case 1:
-               di->charge_otg  = 1;
+       case USB_OTG_POWER_ON:
+               dev_info(di->dev, "charge disable, otg enable\n");
+               di->charge_otg  = USB_OTG_POWER_ON;
                rk81x_bat_set_bit(di, NT_STS_MSK_REG2, PLUG_IN_INT);
                rk81x_bat_set_bit(di, NT_STS_MSK_REG2, PLUG_OUT_INT);
                queue_delayed_work(di->wq, &di->charge_check_work,
                                   msecs_to_jiffies(50));
-               DBG("charge disable OTG enable\n");
                break;
-       case 2:
-               poweron_lowerpoer_handle(di);
+
+       case USB_OTG_POWER_OFF:
+               dev_info(di->dev, "charge enable, otg disable\n");
+               di->charge_otg = USB_OTG_POWER_OFF;
+               rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_IN_INT);
+               rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_OUT_INT);
+               queue_delayed_work(di->wq, &di->charge_check_work,
+                                  msecs_to_jiffies(50));
                break;
        default:
                return NOTIFY_OK;
@@ -3900,8 +3893,13 @@ static void rk81x_bat_irq_init(struct rk81x_battery *di)
 static void rk81x_bat_info_init(struct rk81x_battery *di,
                                struct rk818 *chip)
 {
+       u8 val;
        unsigned long time_base = get_runtime_sec();
 
+       rk81x_bat_read(di, RK818_VB_MON_REG, &val, 1);
+       if (val & PLUG_IN_STS)
+               rk81x_bat_set_power_supply_state(di, USB_CHARGER);
+
        di->cell.config = di->pdata->cell_cfg;
        di->design_capacity = di->pdata->cell_cfg->design_capacity;
        di->qmax = di->pdata->cell_cfg->design_qmax;
@@ -3933,7 +3931,6 @@ static void rk81x_bat_dc_det_init(struct rk81x_battery *di,
        if (gpio_is_valid(di->dc_det_pin))
                di->dc_det_level = (flags & OF_GPIO_ACTIVE_LOW) ?
                                        RK818_DC_IN : RK818_DC_OUT;
-
        di->dc_det_irq = gpio_to_irq(di->dc_det_pin);
        ret = request_irq(di->dc_det_irq, rk81x_vbat_dc_det,
                          IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
@@ -4201,11 +4198,12 @@ static int rk81x_battery_probe(struct platform_device *pdev)
        queue_delayed_work(di->wq, &di->battery_monitor_work,
                           msecs_to_jiffies(TIMER_MS_COUNTS * 5));
 
+#if defined(CONFIG_ARCH_ROCKCHIP)
        INIT_DELAYED_WORK(&di->charge_check_work,
                          rk81x_battery_charge_check_work);
        di->battery_nb.notifier_call = rk81x_bat_notifier_call;
-       register_battery_notifier(&di->battery_nb);
-
+       rk_bc_detect_notifier_register(&di->battery_nb, &di->charge_otg);
+#endif
        dev_info(di->dev, "battery driver version %s\n", DRIVER_VERSION);
 
        return ret;
@@ -4225,6 +4223,7 @@ static int rk81x_battery_suspend(struct platform_device *dev,
        di->dischrg_normal_base = 0;
        di->dischrg_emu_base = 0;
        do_gettimeofday(&di->suspend_rtc_base);
+
        if (!rk81x_chrg_online(di)) {
                di->chrg_save_sec += rk81x_bat_save_chrg_sec(di);
                di->chrg_normal_base = 0;
@@ -4253,11 +4252,18 @@ static int rk81x_battery_resume(struct platform_device *dev)
        int delta_time;
        int time_step;
        int delta_soc;
+       int vol;
 
        di->discharge_smooth_status = true;
        di->charge_smooth_status = true;
        di->s2r = 1;
-       di->voltage  = rk81x_bat_get_vol(di);
+       vol  = rk81x_bat_get_vol(di);
+       if (vol < INVALID_VOL_THRESD) {
+               dev_err(di->dev, "invalid voltage :%d", vol);
+               vol = di->voltage;
+               dbg_enable = 1;
+       }
+       di->voltage = vol;
        di->current_avg = rk81x_bat_get_avg_current(di);
        di->relax_voltage = rk81x_bat_get_relax_vol(di);
        di->est_ocv_vol = rk81x_bat_est_ocv_vol(di);
@@ -4265,7 +4271,7 @@ static int rk81x_battery_resume(struct platform_device *dev)
        delta_time = rk81x_bat_get_suspend_sec(di);
        di->suspend_time_sum += delta_time;
 #if defined(CONFIG_ARCH_ROCKCHIP)
-       di->remain_capacity= rk81x_bat_get_realtime_capacity(di);
+       di->remain_capacity = rk81x_bat_get_realtime_capacity(di);
 #endif
 
        if (di->slp_psy_status) {
@@ -4291,6 +4297,7 @@ static int rk81x_battery_resume(struct platform_device *dev)
        if ((!rk81x_chrg_online(di) && di->voltage <= pwroff_thresd) ||
            rk81x_chrg_online(di))
                wake_lock_timeout(&di->resume_wake_lock, 5 * HZ);
+
        /*
         * do not modify the g_base_sec
         */
@@ -4315,6 +4322,8 @@ static void rk81x_battery_shutdown(struct platform_device *dev)
        struct rk81x_battery *di = platform_get_drvdata(dev);
 
        cancel_delayed_work_sync(&di->battery_monitor_work);
+       rk_bc_detect_notifier_unregister(&di->battery_nb);
+
        if (BASE_TO_MIN(di->power_on_base) <= REBOOT_INTER_MIN)
                rk81x_bat_check_reboot(di);
        else