smp启动-time_init-注册CPUHP_AP_ARM_ARCH_TIMER_STARTING的回调函数
上一篇:init_IRQ():设置中断栈,调用of_irq_init初始化中断控制器,其中会注册CPUHP_AP_IRQ_GIC_STARTING的回调函数gic_starting_cpu
https://www.cnblogs.com/zhangzhiwei122/p/16092659.html
参考-总流程:https://www.cnblogs.com/pengdonglin137/p/11925299.html
10、time_init() 调用 drivers/clocksource/arm_arch_timer.c 中 arch_timer_of_init 注册CPUHP_AP_ARM_ARCH_TIMER_STARTING的回调函数
start_kernel -> time_init
848asmlinkage __visible void __init __no_sanitize_address start_kernel(void) 849{ 972 time_init();
time_init
arch/arm64/kernel/time.c
59 - 调用 timer_probe - 在 drivers/clocksource/timer-probe.c
54void __init time_init(void) 55{ 56 u32 arch_timer_rate; 57 58 of_clk_init(NULL); 59 timer_probe(); 71}
timer_probe
drivers/clocksource/timer-probe.c
11extern struct of_device_id __timer_of_table[]; 16void __init timer_probe(void) 17{ 24 for_each_matching_node_and_match(np, __timer_of_table, &match) { 28 init_func_ret = match->data; 29 30 ret = init_func_ret(np); 31 if (ret) { 32 if (ret != -EPROBE_DEFER) 33 pr_err("Failed to initialize '%pOF': %d\n", np, 34 ret); 35 continue; 36 } 37 38 timers++; 39 } 40 41 timers += acpi_probe_device_table(timer); 42 43 if (!timers) 44 pr_crit("%s: no matching timers found\n", __func__); 45}
24 - for each mathing node and match 扫描 dtb 中的 节点,匹配 __timer_of_table 数组中的 of_device_id 对象。
__timer_of_table 指向 kernel 镜像中的 特殊 节 __timer_of_table,这个节里面都是 kernel 中编译的 timer 的of_device_id 对象。
示例:
drivers/clocksource/arm_arch_timer.c , 匹配 dtb 中 arm,armv7-timer 节点
1324TIMER_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_of_init); 1325TIMER_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_of_init); 1326
28 和 30 行,匹配成功后,调用 of_device_id 对象的 data 字段 指示的函数。 如上面示例,就是 drivers/clocksource/arm_arch_timer.c arch_timer_of_init
arch_timer_of_init
drivers/clocksource/arm_arch_timer.c
1272 的 arch_timer_of_init 调用1090 的 arch_timer_register
1090 的arch_timer_register 在1138 处使用 cpu hotplug 模块函数,注册 CPUHP_AP_ARM_ARCH_TIMER_STARTING 回调 arch_timer_starting_cpu 和 arch_timer_dying_cpu
1089 1090static int __init arch_timer_register(void) 1091{ 1137 /* Register and immediately configure the timer on the boot CPU */ 1138 err = cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_STARTING, 1139 "clockevents/arm/arch_timer:starting", 1140 arch_timer_starting_cpu, arch_timer_dying_cpu); 1158} 1272static int __init arch_timer_of_init(struct device_node *np) 1273{ 1315 ret = arch_timer_register(); 1316 if (ret) 1317 return ret; 1323}