linux clk_clk_set_parent-程序员宅基地

内核: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);



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/luckywang1103/article/details/39031363

智能推荐

SpringBoot基于RateLimiter+AOP动态的为不同接口限流(转载)_ratelimiter 接口限流-程序员宅基地

限流实现RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。依赖包<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-st..._ratelimiter 接口限流

BoCloud博云获得CNCF Kubernetes服务提供商认证-程序员宅基地

近日,BoCloud博云正式获得 CNCF 和 Linux 基金认证的 Kubernetes 服务提供商资质(KCSP),此认证证明BoCloud博云在 Kubernetes 社区从事活动(包括积极贡献代码)、支持企业最终用户的商业模式、以及将工程师派驻客户现场这三面具有相应的技术实力。KCSP 计划(全称 Kubernetes Certified Service Provider)是由 CNCF...

(OK) Android Studio 3.2 中创建新的AVD时,出现错误(No space left on device)—— on Fedora 27-程序员宅基地

To install:- Google APIs Intel x86 Atom System Image (system-images;android-27;google_apis;x86)Preparing "Install Google APIs Intel x86 Atom System Image (revision: 5)".Downloading https://dl.google.c...

服务器响应头cache设置,javascript,node.js_node静态文本服务器设置响应头响应时添加Expires头和Cache-Control: max-age头失败,javascript,..._DarwinYue的博客-程序员宅基地

node静态文本服务器设置响应头响应时添加Expires头和Cache-Control: max-age头失败我自己尝试写了一个node的静态文本服务器,可是设置响应头响应时添加Expires头和Cache-Control: max-age头老是失败。这个是server.jsconst http = require('http');const parse = require('url').pars..._node里设置响应头没有效果

matlab 英语怎么读,MATLAB SPTooL-程序员宅基地

Image:114994698204558.jpgmatlabmatlab是矩阵实验室(matrix laboratory)之意。除具备卓越的数值计算能力外,它还提供了专业水平的符号计算,文字处理,可视化建模仿真和实时控制等功能。matlab的基本数据单位是矩阵,它的指令表达式与数学,工程中常用的形式十分相似,故用matlab来解算问题要比用c,fortran等语言完相同的事情简捷得多.在新的版本..._matlab怎么读

UNIX/Linux系统调用下的文件操作_unix在其他文件调用另一个文件代码-程序员宅基地

系统调用UNIX/Linux系统绝大部分功能都是通过系统调用实现,比如:open/close…UNIX/Linux把系统调用都封装成了C函数的形式,但他们并不是标准C的一部分。一切皆文件在UNIX/Linux系统下,几乎所有资源都是以文件形式提供了,所以在UNIX/Linux系统下一切皆文件,操作系统把它的服务、功能、设备抽象成简单的文件,提供一套简单统一的接口,这样程序就可以像访问磁盘上..._unix在其他文件调用另一个文件代码

随便推点

动态绑定src遇到的问题-程序员宅基地

在动态绑定src时遇到了一个问题,具体的原因还不知道是什么,以下是百度得到的方法:这里以vue-cli中的项目为例:还原事故现场在vue中正常引入时:图片可以正常显示当进行如下修改:这时,图片显示不出奇怪的是在控制台中:这里应该是webpack解析方面的问题,未深入研究解决方法通过require引入而通过src直接写入和require引入,其显示均为:这里还需要...

NAS自动挂载和关闭硬盘电源原理_freenas 退出磁盘-程序员宅基地

家里自配的NAS,没用那些NAS方案,比如FreeNAS或者群辉。就自己捣鼓一套CentOS完事。ZFS之类的,考察下来不适合家用。我用Snapraid + MergerFS + Samba 方案。6 x 3T能耗有些高,待机75w。其实平时可以关闭一些不用的硬盘,这样可以节能减耗。方法和思路如下:1.硬盘都挂于 /disk 目录下。用 autofs管理。/dev/sdb1..._freenas 退出磁盘

HTTP Servlet应用编程接口-程序员宅基地

HTTP Servlet 使用一个 HTML 表格来发送和接收数据。要创建一个 HTTP Servlet,请扩展 HttpServlet 类, 该类是用专门的方法来处理 HTML 表格的 GenericServlet 的一个子类。 HTML 表单是由 和 标记定义的。表单中典型地包含输入字段(如文本输入字段、复选框、单选按钮和选择列表)和用于提交数据的按钮。当提交信息时,它们还指定服务器应执行

Java对图片Base64转码--HTML对Base64解码 [ Java加强版 ]_www.sexzoa18.me-程序员宅基地

Java对图片Base64编码 package base64; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io_www.sexzoa18.me

Linq to sql用法解析---join-程序员宅基地

说明:实例是以Northwind数据库为准 目的:两个表连接,筛选出每个customer所对应的订单数量(两个方法)用join关联两张表,这也是很自然的一个方法var v = from u in entities.Customers join n in entities.Orders on u.Custome

String小案例--从键盘循环录入字符串,输入“end“表示结束,将字符串转换大小写,并统计字母个数的实现_怎么让键盘键入转换成数组形式的数字串以end结束-程序员宅基地

(1)从键盘循环录入录入一个字符串,输入"end"表示结束(2)将字符串中大写字母变成小写字母,小写字母变成大写字母,其它字符用"*"代替,并统计字母的个数举例:键盘录入:Hello12345World输出结果:hELLO*****wORLD总共10个字母代码:import java.util.Scanner;public class Demo07 { public static void main(String[] args) { System.out.println("请输入一个_怎么让键盘键入转换成数组形式的数字串以end结束

推荐文章

热门文章

相关标签