Linux驱动修炼之道-clock框架

努力成为linux kernel hacker的人李万鹏原创作品,为梦而战。转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2011/05/17/6426203.aspx

内核启动时,会调用s3c24xx_register_clock函数注册很多时钟,所谓注册,就是在一个链表中保存各种"struct clk*"结构指针,这些"struct clk"结构有:clk_f(表示FCLK),clk_h(表示HCLK),clk_p(表示PCLK)等。然后可以通过clk_get_rate函数获得获得某类时钟频率。下面到内核中分析一下源码,这里跟踪内核启动时clock system的初始化过程:

start_kernel调用了setup_arch(&command_line):

setup_arch调用了paging_init(mdesc):

paging_init调用了devicemaps_init(mdesc):

在我们板子的文件中查到这个map_io函数:

这个函数有一句s3c24xx_init_clocks(12000000);跟踪进去:

这个函数是设置晶振的频率为12M,也就是我板子上的晶振12M。注意这里最后一句:(cpu->init_clocks)(xtal);我们要查看cpu_table了。

在cpu_table中可以找到这个init_clocks函数,也就是我们苦苦寻觅的clock system初始化函数了,真是众里寻他千百度,那人却在灯火阑珊处。

这个s3c244x_init_clocks完成了clock system全部的初始化工作。现在一个一个来分析里边的3个函数。s3c24xx_register_baseclocks()函数在arch/arm/plat-s3c/clock.c中实现如下:这里对基本的时钟clk_xtal,clk_mpll,clk_upll,clk_f,clk_h,clk_p进行了注册。

下边看一下这个注册函数,主要任务就是把struct clk结构添加到clocks链表中。

这个是链表的头的注册函数。注册的struct clk结构体都要添加到这个clocks链表中。

现在来看第二个函数:它的任务就是设置fclk,hclk,pclk,相信如果认真写过arm裸机程序的人一定很容易看懂下边的代码了,可以对照s3c2440的手册来看的。

这里调用了一个s3c24xx_setup_clocks函数,下面看它的实现:

就是把得到的fclk,hclk,pclk赋值相应结构体。
下面来看第三个函数,这个主要就是对外设的struct clk进行注册。这个函数一共分两部分,有两个数组,一个是init_clocks,也就是在boot时需要提供时钟的,一个是init_clocks_disable,这里的每个成员都是在boot的时候需要disable时钟的。这两个数组分别进行注册,但是注册init_clocks_disable数组中成员的for循环中调用了s3c2410_clkcon_enable(clkp, 0);也就是将相应的clk disable掉。

在arch/arm/plat-s3c/clock.c中实现了clock system对外提供的接口:

你可能感兴趣的:(linux,框架,F#,Blog,Access)