大家帮我看看clk_get究竟是怎么实现的。谢谢

pcwung 2010-09-13 08:22:20

linux-2.6.21.5/arch/arm/plat-s3c24xx/clock.c
/* Clock API calls */

struct clk *(struct device *dev, const char *id)
{
struct clk *p;
struct clk *clk = ERR_PTR(-ENOENT);
int idno;

if (dev == NULL || dev->bus != &platform_bus_type)
idno = -1;
else
idno = to_platform_device(dev)->id;

mutex_lock(&clocks_mutex);

list_for_each_entry(p, & clocks, list) {
if (p->id == idno &&
strcmp(id, p->name) == 0 &&
try_module_get(p->owner)) {
clk = p;
break;
}
}

/* check for the case where a device was supplied, but the
* clock that was being searched for is not device specific */

if (IS_ERR(clk)) {
list_for_each_entry(p, &clocks, list) {
if (p->id == -1 && strcmp(id, p->name) == 0 &&
try_module_get(p->owner)) {
clk = p;
break;
}
}
}

mutex_unlock(&clocks_mutex);
return clk;
}



#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))

说白了define list_for_each_entry 就是一个for循环。。。。



怎么和
struct clk clk_xtal = {
.name = "xtal",
.id = -1,
.rate = 0,
.parent = NULL,
.ctrlbit = 0,
};

这些结构体联系起来的呢???
...全文
152 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
pcwung 2010-09-14
  • 打赏
  • 举报
回复
struct clk {
struct list_head node;
const char *name; /* unique clock name */
const char *function; /* function of the clock */
struct device *dev; /* device associated with function */
unsigned long rate_hz;
struct clk *parent;
u32 pmc_mask;
void (*mode)(struct clk *, int);
unsigned id:2; /* PCK0..3, or 32k/main/a/b */
unsigned type; /* clock type */
u16 users;
};


static struct clk isi_clk = {
.name = "isi_clk",
.pmc_mask = 1 << AT91CAP9_ID_ISI,
.type = CLK_TYPE_PERIPHERAL,
};


static void __clk_enable(struct clk *clk)
{
if (clk->parent)
__clk_enable(clk->parent);
if (clk->users++ == 0 && clk->mode)
clk->mode(clk, 1);
}

int clk_enable(struct clk *clk)
{
unsigned long flags;

spin_lock_irqsave(&clk_lock, flags);
__clk_enable(clk);
spin_unlock_irqrestore(&clk_lock, flags);
return 0;
}
EXPORT_SYMBOL(clk_enable);


/* Register a new clock */
int __init clk_register(struct clk *clk)
{
if (clk_is_peripheral(clk)) {
clk->parent = &mck;
clk->mode = pmc_periph_mode;
list_add_tail(&clk->node, &clocks);
}
else if (clk_is_sys(clk)) {
clk->parent = &mck;
clk->mode = pmc_sys_mode;

list_add_tail(&clk->node, &clocks);
}
#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
else if (clk_is_programmable(clk)) {
clk->mode = pmc_sys_mode;
init_programmable_clock(clk);
list_add_tail(&clk->node, &clocks);
}
#endif

return 0;
}


/*
* Several unused clocks may be active. Turn them off.
*/
static int __init at91_clock_reset(void)
{
unsigned long pcdr = 0;
unsigned long scdr = 0;
struct clk *clk;

list_for_each_entry(clk, &clocks, node) {
if (clk->users > 0)
continue;

if (clk->mode == pmc_periph_mode)
pcdr |= clk->pmc_mask;

if (clk->mode == pmc_sys_mode)
scdr |= clk->pmc_mask;

pr_debug("Clocks: disable unused %s\n", clk->name);
}

at91_sys_write(AT91_PMC_PCDR, pcdr);
at91_sys_write(AT91_PMC_SCDR, scdr);

return 0;
}
late_initcall(at91_clock_reset);


static void pmc_periph_mode(struct clk *clk, int is_on)
{
if (is_on)
at91_sys_write(AT91_PMC_PCER, clk->pmc_mask);
else
at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
}

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧