03.中断流程

内核通知链的使用说明:

注册:

int srcu_notifier_chain_register(struct srcu_notifier_head *nh, struct notifier_block *n);

void srcu_init_notifier_head(struct srcu_notifier_head *nh);

通知:

int srcu_notifier_call_chain(struct srcu_notifier_head *nh, unsigned long val, void *v)

示例:

int charger_dev_event(struct notifier_block *nb, unsigned long event, void *v){... ...}

struct srcu_notifier_head evt_nh;

struct notifier_block chg1_nb;

chg1_nb.notifier_call = charger_psy_event;

srcu_init_notifier_head(&evt_nh);

srcu_notifier_chain_register(&evt_nh, &chg1_nb); 

---------------------------------------------------------------------------------------------------------------------

线程定时器:

 C Code 

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

static enum alarmtimer_restart mtk_charger_alarm_timer_func(struct alarm *alarm, ktime_t now)
{
    struct charger_manager *info =
    container_of(alarm, struct charger_manager, charger_timer);
    unsigned long flags;

    if (info->is_suspend == false) {
        chr_err("%s: not suspend, wake up charger\n", __func__);
        _wake_up_charger(info);
    } else {
        chr_err("%s: alarm timer timeout\n", __func__);
        spin_lock_irqsave(&info->slock, flags);
        if (!info->charger_wakelock.active)
            __pm_stay_awake(&info->charger_wakelock);
        spin_unlock_irqrestore(&info->slock, flags);
    }

    return ALARMTIMER_NORESTART;
}
static void mtk_charger_start_timer(struct charger_manager *info)
{
    struct timespec time, time_now;
    ktime_t ktime;
    int ret = 0;

    /* If the timer was already set, cancel it */
    ret = alarm_try_to_cancel(&pinfo->charger_timer);
    if (ret < 0) {
        chr_err("%s: callback was running, skip timer\n", __func__);
        return;
    }

    get_monotonic_boottime(&time_now);
    time.tv_sec = info->polling_interval;
    time.tv_nsec = 0;
    info->endtime = timespec_add(time_now, time);

    ktime = ktime_set(info->endtime.tv_sec, info->endtime.tv_nsec);

    chr_err("%s: alarm timer start:%d, %ld %ld\n", __func__, ret,
        info->endtime.tv_sec, info->endtime.tv_nsec);
    alarm_start(&pinfo->charger_timer, ktime);
}
static void mtk_charger_init_timer(struct charger_manager *info)
{
    alarm_init(&info->charger_timer, ALARM_BOOTTIME,
            mtk_charger_alarm_timer_func);
    mtk_charger_start_timer(info);

#ifdef CONFIG_PM
    if (register_pm_notifier(&charger_pm_notifier_func))
        chr_err("%s: register pm failed\n", __func__);
#endif /* CONFIG_PM */
}

充电中断流程:

 C Code 

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

/kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

/kernel-4.19/drivers/power/supply/mt6357-charger-type.c
pmic_chrdet_init //pmic_register_interrupt_callback(INT_CHRDET_EDGE, chrdet_int_handler); pmic_enable_interrupt(INT_CHRDET_EDGE, 1, "PMIC");
    ->chrdet_int_handler
        ->pmic_set_register_value(PMIC_RG_USBDL_RST, 1);
        ->do_charger_detect()
            ->mtk_pmic_enable_chr_type_det(pmic_get_register_value(PMIC_RGS_CHRDET))
                ->if (!mt_usb_is_device()) { return;}
                ->g_chr_type = hw_charging_get_charger_type();  //获取硬件充电类型
                ->chrdet_inform_psy_changed(g_chr_type, 1);
power_supply_core.c ->static struct power_supply *chrdet_psy = power_supply_get_by_name("charger"); //pmic_chrdet_init(void)

                    ->propval.intval = chg_type;
                    ->power_supply_set_property(chrdet_psy, POWER_SUPPLY_PROP_ONLINE, &propval)
                    ->power_supply_set_property(chrdet_psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &propval)
                        ->psy->desc->set_property   //psy->desc = &mt_chg->chg_desc in power_supply_register()
mtk_chg_type_det.c          ->mt_charger_set_property   //mt_chg->chg_desc.set_property = mt_charger_set_property
                                ->switch (psp) {
                                ->case POWER_SUPPLY_PROP_ONLINE:
                                    ->mtk_chg->chg_online = val->intval;
                                    ->mt_charger_online(mtk_chg);
                                        ->if (!mtk_chg->chg_online) {   //如果充电器不存在
                                            ->boot_mode = get_boot_mode();
                                            ->if (boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT || boot_mode == LOW_POWER_OFF_CHARGING_BOOT) {
                                                ->kernel_power_off()    //如果是关机充电模式,则关机
                                                ->orderly_poweroff(true)    //使用这个,上面的没作用
                                ->case POWER_SUPPLY_PROP_CHARGE_TYPE:
                                    ->mtk_chg->chg_type = val->intval;//将g_chr_type保存在struct mt_charger *mtk_chg,以供mt_get_charger_type()使用
                                ->if (mtk_chg->chg_type == STANDARD_HOST/CHARGING_HOST/NONSTANDARD_CHARGER)
                                    ->mt_usb_connect();  //连接PC
                                    ->info->vbus_state = 1;
                                ->else
                                    ->mt_usb_disconnect();
                                    ->info->vbus_state = 0;
                                ->queue_work(cti->chg_in_wq, &cti->chg_in_work);    //INIT_WORK(&cti->chg_in_work, charger_in_work_handler);
                                    ->charger_in_work_handler
mtk_charger.c                           ->mtk_charger_int_handler
                                            ->charger_manager_notifier(pinfo, CHARGER_NOTIFY_STOP_CHARGING);    //if (mt_get_charger_type() == CHARGER_UNKNOWN) {
                                            ->charger_manager_notifier(pinfo, CHARGER_NOTIFY_START_CHARGING);   //else
notifier.c                                      ->srcu_notifier_call_chain(&info->evt_nh, event, NULL); //int srcu_notifier_call_chain(struct srcu_notifier_head *nh, unsigned long val, void *v)
                                                    ->battery_callback
                                            ->_wake_up_charger(pinfo)
                                                ->wake_up(&info->wait_que)
                                                    ->charger_routine_thread
mtk_battery_core.c                      ->fg_charger_in_handler
mtk_chg_type_det.c                          ->mt_get_charger_type  //去拿充电类型
mtk_battery.c                               ->wakeup_fg_algo_atomic(FG_INTR_CHARGER_IN)  //唤醒gm3.0算法
                                                ->nl_send_to_user(gm.g_fgd_pid, 0, fgd_msg);
                                ->queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, info->debounce_jiffies); //INIT_DELAYED_WORK(&info->wq_detcable, usb_extcon_detect_cable);
                                   ->usb_extcon_detect_cable 
                                        ->if (info->vbus_state)
                                            ->extcon_set_state_sync(info->edev, EXTCON_USB, true);
                                        ->else
                                            ->extcon_set_state_sync(info->edev, EXTCON_USB, false);
                                                ->ssusb_vbus_notifier(struct notifier_block *nb, unsigned long event, void *ptr)
                                                    ->if (event)
                                                        ->ssusb_set_mailbox(otg_sx, MTU3_VBUS_VALID);
                                                    ->else
                                                        ->ssusb_set_mailbox(otg_sx, MTU3_VBUS_OFF);
power_supply_core.c             ->power_supply_changed(mtk_chg->ac_psy);
                                    ->schedule_work(&psy->changed_work)
                                ->power_supply_changed(mtk_chg->usb_psy);
                                    ->schedule_work(&psy->changed_work) //INIT_WORK(&psy->changed_work, power_supply_changed_work);
                                        ->power_supply_changed_work(struct work_struct *work)
notifier.c                                  ->atomic_notifier_call_chain(&power_supply_notifier, PSY_EVENT_PROP_CHANGED, psy);
                                                ->__atomic_notifier_call_chain(nh, val, v, -1, NULL)
                                                    ->notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
mtk_power_misc.c                                        ->int mtk_power_misc_psy_event(struct notifier_block *nb, unsigned long event, void *v)
                                                            ->if (strcmp(psy->desc->name, "battery") == 0) {
                                                                ->psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
mtk_battery.c                                                       ->int battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
                                                                ->wake_up_overheat(&sdc);
                                                        ->int charger_psy_event(struct notifier_block *nb, unsigned long event, void *v)
                                                            ->if (strcmp(psy->desc->name, "battery") == 0)
                                                                ->power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
                                                                    ->int battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
                                                                ->_wake_up_charger(info);

 C Code 

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

mtk_charger.c   static int charger_routine_thread(void *arg)
                    ->if (!info->charger_wakelock.active)
                        __pm_stay_awake(&info->charger_wakelock);   //增加combined_event_count计数
                    ->chr_err("Vbat=%d,Ibat=%d,I=%d,VChr=%d,T=%d,Soc=%d:%d,CT:%d:%d hv:%d pd:%d:%d\n",
                    ->is_charger_on = mtk_is_charger_on(info)
                        ->chr_type = mt_get_charger_type(); //去拿充电类型
                            ->return mtk_chg->chg_type;
                        ->if (chr_type == CHARGER_UNKNOWN && info->chr_type != CHARGER_UNKNOWN) {
                            ->mtk_charger_plug_out(info);
                                ->info->chr_type = CHARGER_UNKNOWN;
                                ->info->charger_thread_polling = false;
                                ->info->plug_out(info);
mtk_switch_charging.c               ->int mtk_switch_charging_plug_out(struct charger_manager *info)
                                        ->swchgalg->total_charging_time = 0;
                                ->wakeup_sc_algo_cmd(&pinfo->sc.data, SC_EVENT_PLUG_OUT, 0);
charger_class.c                 ->charger_dev_set_input_current(info->chg1_dev, 100000);    //info->chg1_dev = get_charger_by_name("primary_chg");
                                ->charger_dev_plug_out(info->chg1_dev);
                                    ->chg_dev->ops->plug_out(chg_dev)   //hl7019没实现,不会报错吗
                        ->else if (info->chr_type == CHARGER_UNKNOWN)
                            ->mtk_charger_plug_in(info, chr_type);
                                ->info->chr_type = chr_type;
                                ->info->charger_thread_polling = true;
                                ->info->can_charging = true;
                                ->info->plug_in(info)
mtk_switch_charging.c               ->int mtk_switch_charging_plug_in(struct charger_manager *info)
                                        ->swchgalg->state = CHR_CC;
                                        ->info->polling_interval = CHARGING_INTERVAL;  //10s
                                        ->get_monotonic_boottime(&swchgalg->charging_begin_time);   //保存充电启示时间
                                ->wakeup_sc_algo_cmd(&pinfo->sc.data, SC_EVENT_PLUG_IN, 0);
charger_class.c                 ->charger_dev_set_input_current(info->chg1_dev, info->chg1_data.input_current_limit);
                                ->charger_dev_plug_in(info->chg1_dev);
                                    ->chg_dev->ops->plug_in(chg_dev)    //hl7019没实现,不会报错吗
                    ->if (info->charger_thread_polling == true)
                        ->mtk_charger_start_timer(info);    //开启定时器用于唤醒线程
                            ->alarm_start(&pinfo->charger_timer, ktime);
mtk_charger.c       ->charger_update_data(info) //检查电池温度
                    ->check_battery_exist(info)
                    ->check_dynamic_mivr(info)
                    ->charger_check_status(info)    //检查充电过程中温度、时间、vbus电压等等,拔插中断不会跑
                        ->charging = true/false;    //先默认为true,然后根据不同状态决定是否赋值false

                        ->if (!mtk_chg_check_vbus(info))  //检查充电器vbus电压

                            ->charging = false;

                        ->if (mt_get_charger_type() == CHARGER_UNKNOWN) //如果是拔出充电器状态,那么直接return;

                            ->return;

                        ->mtk_battery_notify_check(info);

                            ->mtk_battery_notify_VCharger_check(info);  //检查充电器电压

                            ->mtk_battery_notify_VBatTemp_check(info);  //检查电池温度
                        ->if (charging != info->can_charging)   //如果状态发生改变(充电器插入时,一般这里不会跑,因为这两个值都是true)
                            ->_charger_manager_enable_charging(info->chg1_consumer,0, charging);
                                ->_mtk_charger_do_charging(info, en);
                                    ->info->do_charging(info, en);
                                        ->mtk_switch_charging_do_charging(struct charger_manager *info, bool en)
                                            ->if (en)
                                                ->algo_data->disable_charging = false;
                                                ->algo_data->state = CHR_CC;
                                                ->charger_manager_notifier(info, CHARGER_NOTIFY_NORMAL);
                                                    ->int battery_callback(struct notifier_block *nb, unsigned long event, void *v)
                                                        ->battery_main.BAT_STATUS = POWER_SUPPLY_STATUS_CHARGING;
                                                        ->battery_update(&battery_main);
                                            ->else
                                                ->algo_data->disable_charging = true;
                                                ->algo_data->state = CHR_ERROR;
                                                ->charger_manager_notifier(info, CHARGER_NOTIFY_ERROR);
                                                    ->int battery_callback(struct notifier_block *nb, unsigned long event, void *v)
                                                        ->battery_main.BAT_STATUS = POWER_SUPPLY_STATUS_NOT_CHARGING;
                                                        ->battery_update(&battery_main);
                                                ->_disable_all_charging(info);
                                                    ->charger_dev_enable(info->chg1_dev, false);
                    ->kpoc_power_off_check(info)
                        ->boot_mode = get_boot_mode();
                        ->if (boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT || boot_mode == LOW_POWER_OFF_CHARGING_BOOT) {
                            ->orderly_poweroff(true);   //if (system_state != SYSTEM_POWER_OFF) //system_state是整个系统的全局变量
                    ->if (is_charger_on == true) {
                        ->info->do_algorithm(info);
mtk_switch_charging.c       ->mtk_switch_charging_run(struct charger_manager *info)
                                ->struct switch_charging_alg_data *swchgalg = info->algorithm_data
                                ->switch (swchgalg->state) {
                                ->case CHR_CC:
                                    ->mtk_switch_chr_cc(info)
                                        ->get_monotonic_boottime(&time_now);    //获取当前时间
                                        ->charging_time = timespec_sub(time_now, swchgalg->charging_begin_time);    //相减得到充电时间
                                        ->swchg_turn_on_charging(info)
                                            ->swchg_select_charging_current_limit(info) //如果不是META_BOOT
                                                ->struct charger_data *pdata = &info->chg1_data;
                                                ->charger_dev_set_input_current(info->chg1_dev, pdata->input_current_limit)
                                                    ->chg_dev->ops->set_input_current(chg_dev, uA)  //kernel-4.14/drivers/power/supply/mediatek/charger/hl7019.c
                                                ->charger_dev_set_charging_current(info->chg1_dev, pdata->charging_current_limit)
                                                    ->chg_dev->ops->set_charging_current(chg_dev, uA)
                                                ->/*If thermal current limit is larger than charging IC's minimum current setting, enable the charger immediately*/
                                                    ->charger_dev_enable(info->chg1_dev, true);
                                            ->swchg_select_cv(info);
                                                ->charger_dev_set_constant_voltage(info->chg1_dev, constant_voltage);
                                            ->charger_dev_enable(info->chg1_dev, charging_enable)
                                                ->chg_dev->ops->enable(chg_dev, en)
                                        ->charger_dev_is_charging_done(info->chg1_dev, &chg_done);  //读取充电IC CHRG_STAT状态,判断是否充满
                                            ->chg_dev->ops->is_charging_done(chg_dev, done);
                                        ->if (chg_done)
                                            ->swchgalg->state = CHR_BATFULL;
                                            ->charger_dev_do_event(info->chg1_dev, EVENT_EOC, 0);
                                                ->chg_dev->ops->event(chg_dev, event, args);
                                                    ->charger_dev_notify(chg_dev, CHARGER_DEV_NOTIFY_EOC);  //充电IC驱动的.event()会调用charger_dev_notify()
                                                        ->srcu_notifier_call_chain(&chg_dev->evt_nh, event, &chg_dev->noti);

                                                           ->int charger_dev_event(struct notifier_block *nb, unsigned long event, void *v)  //??
                                ->case CHR_BATFULL:
                                    ->mtk_switch_chr_full(info);
                                        ->swchg_select_cv(info);    //如果被JEITA降低了,这里重新设回来
                                        ->info->polling_interval = CHARGING_FULL_INTERVAL;  //20s
                                        ->charger_dev_is_charging_done(info->chg1_dev, &chg_done);
                                        ->if (!chg_done)
                                            ->swchgalg->state = CHR_CC;
                                            ->get_monotonic_boottime(&swchgalg->charging_begin_time);
                                            ->info->polling_interval = CHARGING_INTERVAL;   
                                ->mtk_switch_check_charging_time(info); //check total charging time
                                ->charger_dev_dump_registers(info->chg1_dev);
                                    ->chg_dev->ops->dump_registers(chg_dev)
mtk_charger.c           ->wakeup_sc_algo_cmd(&pinfo->sc.data, SC_EVENT_CHARGING, 0);
                    ->if (is_charger_on == false) {
                        ->wakeup_sc_algo_cmd(&pinfo->sc.data, SC_EVENT_STOP_CHARGING, 0);
                    __pm_relax(&info->charger_wakelock);   //减少combined_event_count计数

如果温度过高:

/kernel-4.14/drivers/misc/mediatek/thermal/common/coolers/mtk_cooler_bcct_v1.c

chrlmt_set_limit_handler  //INIT_WORK(&bcct_chrlmt_work, chrlmt_set_limit_handler);

  charger_manager_set_charging_current_limit(pthermal_consumer, 0, ((chrlmt_bat_chr_curr_limit != -1) ?chrlmt_bat_chr_curr_limit * 1000 : -1));

    pdata->thermal_charging_current_limit = charging_current;

linear_chg_select_charging_current_limit

  chr_err("force:%d thermal:%d setting:%d type:%d usb_unlimited:%d usbif:%d usbsm:%d\n",
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值