.notifier_call = tick_notify,
};
/**
* tick_init - initialize the tick control
*
* Register the notifier with the clockevents framework
*/
void __init tick_init(void)
{
clockevents_register_notifier(&tick_notifier);
}
这个函数就是注册了上面那个结构体,上面那个结构体 只包括一个回调函数。下面我们分析一下,它是如何注册,之后又是如何回调的呢?
首先
tick_init-->>clockevents_register_notifier-->>raw_notifier_chain_register(&clockevents_chain, nb);
这里我们就不得不提一下clockevents_chain 这个宏了,其实它是一个结构体。
static RAW_NOTIFIER_HEAD(clockevents_chain);
#define RAW_NOTIFIER_HEAD(name) \
struct raw_notifier_head name = \
RAW_NOTIFIER_INIT(name)
#define RAW_NOTIFIER_INIT(name) { \
.head = NULL }
我们将这个宏展开后其实就是
static struct raw_notifier_head clockevents_chain = {
.head = NULL }
而且他还是个静态的。
raw_notifier_chain_register-->>notifier_chain_register-->>
nl = &((*nl)->next);
}
n->next = *nl
这里其实就是把tick_notifier 这个结构体添加到了clockevents_chain 链表里面。
这里的注册就已经结束了,那么tick_notifier 里面的回调函数是何时被调用的呢?
接着看。。看与平台相关的代码
MACHINE_START(SUN7I, "sun7i")
.atag_offset = 0x100,
.timer = &sw_sys_timer,
.map_io = sun7i_map_io,
.init_early = NULL,
.init_irq = gic_init_irq,
.init_machine = sw_core_init,
.reserve = sw_core_reserve,
.restart = sun4i_restart,
#ifdef CONFIG_MULTI_IRQ_HANDLER
.handle_irq = gic_handle_irq,
#endif
#ifdef CONFIG_ZONE_DMA
.dma_zone_size = SZ_256M,
#endif
MACHINE_END
关于这个结构体在以前已经分析过了。
这次我们主要看sw_sys_timer-->>sw_timer_init函数
sw_timer_init-->>aw_clkevt_init()-->>register_clk_dev()-->>clockevents_register_device()-->>clockevents_do_notify()-->>raw_notifier_call_chain(&clockevents_chain, reason, dev);
看到了吗?clockevents_chain 这个链表出现了。
raw_notifier_call_chain-->>__raw_notifier_call_chain-->>notifier_call_chain
nb->notifier_call(nb, val, v); 这里调用了上面的那个回调函数tick_notify。
这个回调函数调用tick_check_new_device 函数,关于这个函数到底干了什么,其实有点深,没看明白,待以后分析吧!!