linux clk
来源:互联网 发布:ubuntu启动盘修复 grub 编辑:程序博客网 时间:2024/05/20 12:24
内核:3.3
平台:rlx
涉及的主要文件有
include/linux/clk.h
drivers/clk/clkdev.c
drivers/clk/clk.c
arch/rlx/bsp/clock.c
1、 clk通用接口
内核定义了一套标准的接口(include/linux/clk.h),用于所有的平台之上。每个时钟源对象使用一个struct clk结构来表示。而struct clk结构的具体内容由各平台自己定义。clk.h头文件定义了操作一个clk对象的所有接口。内核的其他地方可以也只能使用clk.h中提供的这些接口函数来操作clk。
struct clk *clk_get(struct device *dev, const char *id);int clk_enable(struct clk *clk);void clk_disable(struct clk *clk);unsigned long clk_get_rate(struct clk *clk);void clk_put(struct clk *clk);long clk_round_rate(struct clk *clk, unsigned long rate);int clk_set_rate(struct clk *clk, unsigned long rate);int clk_set_parent(struct clk *clk, struct clk *parent);struct clk *clk_get_parent(struct clk *clk);struct clk *clk_get_sys(const char *dev_id, const char *con_id);int clk_add_alias(const char *alias, const char *alias_dev_name, char *id, struct device *dev);
2、这些操作的具体实现在/arch/rlx/bsp/clock.c文件
static const struct clk_ops rlx_divider_ops = {.enable = rlx_enable_clk,.disable = rlx_disable_clk,.round_rate = rlx_round_rate,.set_rate = rlx_set_rate,.set_parent = rlx_set_parent,.get_parent = rlx_get_parent,.recalc_rate = rlx_recalc,};通过一个宏DEFINE_CLK_RLX将这个clk_ops赋值给struct clk结构体中的ops
#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ static struct clk _name = { \ .name = #_name, \ .hw = &_name##_hw.hw, \ .parent_names = _parent_array_name, \ .num_parents = ARRAY_SIZE(_parent_array_name), \ .ops = &_clkops_name, \ };#define DEFINE_CLK_RLX(_name, _clksel,\ _clksel_reg, _clk_change, _parent_names, _ops) \static struct clk _name;\static struct clk_hw_rlx _name##_hw = {\.hw = {\.clk = &_name,\},\.clksel= _clksel,\.clkreg= (void __iomem*)_clksel_reg,\.clk_change= _clk_change,\};\DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
DEFINE_CLK_RLX(i2c_ck, 0, I2C_CLK_CFG_REG, I2C_CLK_CHANGE, rlx_ck_parent_names,rlx_divider_ops);其中ic2_ck是struct clk结构体,这样就将rlx_divider_ops赋给了i2c_clk->ops
3、每个struct clk应该对应一个struct clk_lookup结构,有了他,就可以通过设备名或者时钟源的名字来找到相应的struct clk结构,链表操作位于/drivers/clk/clkdev.c
将每一个clk_lookup通过clkdev_add注册到系统中,其实在clkdev_add函数中是这么实现的
void clkdev_add(struct clk_lookup *cl){mutex_lock(&clocks_mutex);list_add_tail(&cl->node, &clocks);mutex_unlock(&clocks_mutex);}EXPORT_SYMBOL(clkdev_add);就是将lookup节点添加到一个clocks为头的链表中去,其实相当于将struct clk添加到clocks链表中。
4、clk_get、clk_enable
通过/drivers/clk/clkdev.c文件中的clk_find函数在上面的clocks链表中找到匹配的clk_lookup,从而找到对应的struct clk,并返回struct clk
/drivers/clk/clk.c中的clk_enable最终调用的是clk中ops里的方法。
部分摘自:http://www.cnblogs.com/sammei/archive/2012/10/15/3295612.html
总结:
1、clk的注册
2、clk的使用
通常操作为以下几步:
1)定义struct clk *clk;
2)获取需要操作的clock结构体实例
clk=clk_get(&pdev->dev, "i2c_clk");
3)设置clock的source,最终频率由此分频得到
clk_set_parent(clk, clk_get(NULL, "usb_pll"));
4)设置频率
clk_set_rate(clk, 4000000);
5)产生时钟
clk_enable(clk);
6)停止时钟
clk_disable(clk);
- linux clk
- linux clk
- Linux 内核clk 添加clk provider
- Linux clk 模型
- Linux clk 模型
- linux clk的使用
- linux clk模型
- linux clk模型
- linux clk驱动框架
- Linux clk 模型
- Linux 内核clk ops
- linux CLK时钟驱动
- Linux时钟管理clk
- linux clk驱动框架
- Linux clk 模型
- Linux 内核clk框架描述
- Linux 内核clk相关数据结构描述
- Linux 内核clk 硬件相关层
- Python中的模块
- (白书训练计划)UVa 120 Stacks of Flapjacks(构造法)
- 关于win7 64位 只 安装 oracle 10g的client
- jsp页面根据json数据动态生成table
- xml配置方式实现action的所有方法的输入校验
- linux clk
- DNS域名系统
- WEB SOCKET API 通信原理及消息机制
- 黑马程序员--内部类
- spoj 375 Query on a tree 树链剖分
- Qt release之后运行显示it could not find or load the Qt platform plugin "windows".解决方法
- [ExtJS5学习笔记]第十四节 Extjs5中data数据源store和datapanel学习
- 【DP】 HDOJ 4834 JZP Set
- vc 与oc混编