设为首页 加入收藏

TOP

clk_get函数实现,Linux内核时钟框架(一)
2014-11-24 13:33:53 来源: 作者: 【 】 浏览:1
Tags:clk_get 函数 实现 Linux 内核 时钟 框架

(1) 对应外设时钟的开启


struct clk=clk_get(NULL,"adc");


clk.enable();


之后adc对应的时钟位就能时能。


struct clk *clk_get(struct device *dev, const char *id)
{
..........
list_for_each_entry(p, &clocks, list) {
if (p->id == idno &&
strcmp(id, p->name) == 0 &&
try_module_get(p->owner)) {
clk = p;
break;
}
}



.............................................
return clk;
}


clk_get从一个时钟list链表中以字符id名称来查找一个时钟clk结构体并且返回,最后调用clk.enable(),来时能对应的外设时钟源。




(2) list的设置和对应list中的成员。


MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board")
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,


.init_irq = s3c24xx_init_irq,
.map_io = mini2440_map_io,
.init_machine = mini2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END




static void __init mini2440_map_io(void)
{
s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
}




void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
{
unsigned long idcode = 0x0;
...........
arm_pm_restart = s3c24xx_pm_restart;


s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}




void __init s3c_init_cpu(unsigned long idcode,
struct cpu_table *cputab, unsigned int cputab_size)
{
cpu = s3c_lookup_cpu(idcode, cputab, cputab_size);
......
cpu->map_io();


static struct cpu_table cpu_ids[] __initdata = {
.......
{
.idcode = 0x32410002,
.idmask = 0xffffffff,
.map_io = s3c2410_map_io,
.init_clocks = s3c2410_init_clocks,
.init_uarts = s3c2410_init_uarts,
.init = s3c2410a_init,
.name = name_s3c2410a
},
.......
}


在static void __init mini2440_map_io(void)中调用s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc))后返回了struct cpu_table cpu_ids中的


{
.idcode = 0x32410002,
.idmask = 0xffffffff,
.map_io = s3c2410_map_io,
.init_clocks = s3c2410_init_clocks,
.init_uarts = s3c2410_init_uarts,
.init = s3c2410a_init,
.name = name_s3c2410a
}


cpu_table


之后运行s3c24xx_init_clocks(12000000)后又执行(cpu->init_clocks)(xtal),对应就是s3c2410_init_clocks


void __init s3c244x_init_clocks(int xtal)
{
/* initialise the clocks here, to allow other things like the
* console to use them, and to add new ones after the initialisation
*/


s3c24xx_register_baseclocks(xtal); //完成祖宗级别时钟的注册
s3c244x_setup_clocks();//填充祖宗级别时钟结构,方便以后调用
s3c2410_baseclk_add();//添加一些外设时钟结构到list中,并且关闭它们方便省电
}




int __init s3c24xx_register_baseclocks(unsigned long xtal)
{
printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");


clk_xtal.rate = xtal;


/* register our clocks */


if (s3c24xx_register_clock(&clk_xtal) < 0)
printk(KERN_ERR "failed to register master xtal\n");


if (s3c24xx_register_clock(&clk_mpll) < 0)
printk(KERN_ERR "failed to register mpll clock\n");


if (s3c24xx_register_clock(&clk_upll) < 0)
printk(KERN_ERR "failed to register upll clock\n");


if (s3c24xx_register_clock(&clk_f) < 0)
printk(K

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux驱动开发:网络设备之DM9000.. 下一篇Linux等待队列操作

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: