您的位置:首页 > 其它

struct clk *clk_get(struct device *dev, const char *id)

2012-07-17 17:22 316 查看
(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(KERN_ERR "failed to register cpu fclk\n");

if (s3c24xx_register_clock(&clk_h) < 0)

printk(KERN_ERR "failed to register cpu hclk\n");

if (s3c24xx_register_clock(&clk_p) < 0)

printk(KERN_ERR "failed to register cpu pclk\n");

return 0;

}

以上的作用就是将一个个的时钟结构体链接成双向链表的,以后好使用clk_get在时钟结构体链表中查找id字符匹配的clk结构体并返回。

s3c2410_baseclk_add()

{

..........

clkp = init_clocks_disable;

for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {

ret = s3c24xx_register_clock(clkp);

if (ret < 0) {

printk(KERN_ERR "Failed to register clock %s (%d)\n",

clkp->name, ret);

}

s3c2410_clkcon_enable(clkp, 0);

}

........

}

s3c2410_baseclk_add()添加其他外设的clk结构

clk.enable(),最后调用的

static struct clk init_clocks_disable[] = {

......

{

.name = "adc",

.id = -1,

.parent = &clk_p,

.enable = s3c2410_clkcon_enable,

.ctrlbit = S3C2410_CLKCON_ADC,

}

......

}中的

int s3c2410_clkcon_enable(struct clk *clk, int enable)

{

unsigned int clocks = clk->ctrlbit;

unsigned long clkcon;

clkcon = __raw_readl(S3C2410_CLKCON);

if (enable)

clkcon |= clocks;

else

clkcon &= ~clocks;

/* ensure none of the special function bits set */

clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);

__raw_writel(clkcon, S3C2410_CLKCON);

return 0;

}其根据.ctrlbit = S3C2410_CLKCON_ADC,来使能对应ADC时钟。

转自http://blog.csdn.net/shushi0123/article/details/7318816
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: