Linux下系统时钟在初始化时经常用到 CLK_OF_DECLARE 这个宏,现在以 6ul为列做分析:
CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);
CLK_OF_DECLARE 的定义:
#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
OF_DECLARE_1 的定义:
typedef void (*of_init_fn_1)(struct device_node *); //函数指针
#define OF_DECLARE_1(table, name, compat, fn) \
_OF_DECLARE(table, name, compat, fn, of_init_fn_1)
_OF_DECLARE 的定义:
/*
* Struct used for matching a device
*/
struct of_device_id {
char name[32];
char type[32];
char compatible[128];
const void *data;
};
#ifdef CONFIG_OF //CONFIG_OF的定义
#define _OF_DECLARE(table, name, compat, fn, fn_type) \
static const struct of_device_id __of_table_##name \
__used __section(__##table##_of_table) \
= { .compatible = compat, \
.data = (fn == (fn_type)NULL) ? fn : fn }
#else
#define _OF_DECLARE(table, name, compat, fn, fn_type) \
static const struct of_device_id __of_table_##name \
__attribute__((unused)) \
= { .compatible = compat, \
.data = (fn == (fn_type)NULL) ? fn : fn }
#endif
定义了一个 struct of_device_id 的结构体变量
如果定义CONFIG_OF,就将 struct of_device_id 变量放到 __clk_of_table 下;
__clk_of_table 在clk.c 文件下的 of_clk_init() 函数中调用:
void __init of_clk_init(const struct of_device_id *matches)
{
.......
if (!matches)
matches = &__clk_of_table;
.......
}
of_clk_init 在./arch/arm/kernel/time.c:121: of_clk_init(NULL); time_init()函数中被调用:
void __init time_init(void)
{
if (machine_desc->init_time) {
machine_desc->init_time();
} else {
#ifdef CONFIG_COMMON_CLK
of_clk_init(NULL);
#endif
clocksource_of_init();
}
}
time_init 在 start_kernel() 函数中被调用 ./init/main.c:587: time_init();
asmlinkage __visible void __init start_kernel(void)
{
............
time_init();
............
}