当前位置: 首页 > news >正文

Linux内核4.14版本——ccf时钟子系统(5)——通用API

1. clk_get

1.1 __of_clk_get_by_name

1.2 clk_get_sys

2. clk_prepare_enable

2.1 clk_prepare

2.2 clk_enable

3. clk_set_rate


1. clk_get

        clock get是通过clock名称获取struct clk指针的过程,由clk_get、devm_clk_get、clk_get_sys、of_clk_get、of_clk_get_by_name、of_clk_get_from_provider等接口负责实现,这里以clk_get为例,分析其实现过程(位于drivers/clk/clkdev.c中)。

struct clk *clk_get(struct device *dev, const char *con_id)
{const char *dev_id = dev ? dev_name(dev) : NULL;struct clk *clk;if (dev) {clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)return clk;}return clk_get_sys(dev_id, con_id);
}

       该函数用于从目标设备上获取指定标识符的时钟。
       (1)它首先尝试从设备树中获取时钟硬件(通过of_clk_get_hw函数),
       (2)如果成功或者返回-EPROBE_DEFER(延迟探测)时,将创建并返回一个表示时钟的struct clk结构体指针。
       (3)如果在设备树中未找到时钟硬件,将调用clk_get_sys函数尝试从系统时钟表中获取时钟。

1.1 __of_clk_get_by_name

static struct clk *__of_clk_get_by_name(struct device_node *np,const char *dev_id,const char *name)
{struct clk *clk = ERR_PTR(-ENOENT);/* Walk up the tree of devices looking for a clock that matches */while (np) {int index = 0;/** For named clocks, first look up the name in the* "clock-names" property.  If it cannot be found, then* index will be an error code, and of_clk_get() will fail.*/if (name)index = of_property_match_string(np, "clock-names", name);clk = __of_clk_get(np, index, dev_id, name);if (!IS_ERR(clk)) {break;} else if (name && index >= 0) {if (PTR_ERR(clk) != -EPROBE_DEFER)pr_err("ERROR: could not get clock %pOF:%s(%i)\n",np, name ? name : "", index);return clk;}/** No matching clock found on this node.  If the parent node* has a "clock-ranges" property, then we can try one of its* clocks.*/np = np->parent;if (np && !of_get_property(np, "clock-ranges", NULL))break;}return clk;
}

      最终调用__of_clk_get-->__of_clk_get_from_provider,__of_clk_get_from_provider函数我们后面介绍。

1.2 clk_get_sys

struct clk *clk_get_sys(const char *dev_id, const char *con_id)
{struct clk_lookup *cl;struct clk *clk = NULL;mutex_lock(&clocks_mutex);cl = clk_find(dev_id, con_id);if (!cl)goto out;clk = __clk_create_clk(cl->clk_hw, dev_id, con_id);if (IS_ERR(clk))goto out;if (!__clk_get(clk)) {__clk_free_clk(clk);cl = NULL;goto out;}out:mutex_unlock(&clocks_mutex);return cl ? clk : ERR_PTR(-ENOENT);
}

1.2.1 clk_find

/** Find the correct struct clk for the device and connection ID.* We do slightly fuzzy matching here:*  An entry with a NULL ID is assumed to be a wildcard.*  If an entry has a device ID, it must match*  If an entry has a connection ID, it must match* Then we take the most specific entry - with the following* order of precedence: dev+con > dev only > con only.*/
static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
{struct clk_lookup *p, *cl = NULL;int match, best_found = 0, best_possible = 0;if (dev_id)best_possible += 2;if (con_id)best_possible += 1;list_for_each_entry(p, &clocks, node) {match = 0;if (p->dev_id) {if (!dev_id || strcmp(p->dev_id, dev_id))continue;match += 2;}if (p->con_id) {if (!con_id || strcmp(p->con_id, con_id))continue;match += 1;}if (match > best_found) {cl = p;if (match != best_possible)best_found = match;elsebreak;}}return cl;
}static LIST_HEAD(clocks);

       clk_find从系统时钟链表中查找已经注册的时钟,这些时钟是通过函数clk_register_clkdev注册的。

2. clk_prepare_enable

/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
static inline int clk_prepare_enable(struct clk *clk)
{int ret;ret = clk_prepare(clk);if (ret)return ret;ret = clk_enable(clk);if (ret)clk_unprepare(clk);return ret;
}

2.1 clk_prepare

        clk_prepare--->clk_core_prepare_lock--->clk_core_prepare

static int clk_core_prepare(struct clk_core *core)
{int ret = 0;lockdep_assert_held(&prepare_lock);if (!core)return 0;if (core->prepare_count == 0) {// 递归调用 clk_core_prepare 准备时钟源的父时钟ret = clk_core_prepare(core->parent);if (ret)return ret;// 跟踪时钟准备操作trace_clk_prepare(core);// 调用时钟源操作函数的 prepare 函数if (core->ops->prepare)ret = core->ops->prepare(core->hw);// 跟踪时钟准备完成trace_clk_prepare_complete(core);if (ret) {clk_core_unprepare(core->parent);return ret;}}// 增加时钟准备计数core->prepare_count++;return 0;
}

         clk_core_prepare 函数用于准备时钟源。它可能会睡眠,这与 clk_enable 不同。在简单的情况下,如果操作可能会睡眠,可以使用 clk_core_prepare 替代 clk_enable 来启用时钟。在复杂的情况下,时钟解锁操作可能需要一个快速和一个慢速部分。这就是 clk_core_prepare 和clk_enable 不是互斥的原因。实际上,必须在调用 clk_core_prepare 之前调用 clk_enable。

2.2 clk_enable

      enable也是差不多的操作这里不做介绍了。

3. clk_set_rate

      clk_set_rate --> clk_core_set_rate_nolock 

3.1 clk_core_set_rate_nolock 

static int clk_core_set_rate_nolock(struct clk_core *core,unsigned long req_rate)
{struct clk_core *top, *fail_clk;unsigned long rate = req_rate;if (!core)return 0;/* bail early if nothing to do */if (rate == clk_core_get_rate_nolock(core))return 0;if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count)return -EBUSY;/* calculate new rates and get the topmost changed clock */top = clk_calc_new_rates(core, rate);if (!top)return -EINVAL;/* notify that we are about to change rates */fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);if (fail_clk) {pr_debug("%s: failed to set %s rate\n", __func__,fail_clk->name);clk_propagate_rate_change(top, ABORT_RATE_CHANGE);return -EBUSY;}/* change the rates */clk_change_rate(top);core->req_rate = req_rate;return 0;
}

3.1.1 clk_calc_new_rates

3.1.2 clk_propagate_rate_change

3.1.3 clk_change_rate

相关文章:

Linux内核4.14版本——ccf时钟子系统(5)——通用API

1. clk_get 1.1 __of_clk_get_by_name 1.2 clk_get_sys 2. clk_prepare_enable 2.1 clk_prepare 2.2 clk_enable 3. clk_set_rate 1. clk_get clock get是通过clock名称获取struct clk指针的过程,由clk_get、devm_clk_get、clk_get_sys、of_clk_get、of_clk_g…...

安装MySQL 5.7 亲测有效

前言:本文是笔者在安装MySQL5.7时根据另一位博主大大的安装教程基础上做了一些修改而成 首先在这里表示对博主大大的感谢 下面附博主大大地址 下面的步骤言简意赅 跟着做就不会出错 希望各位读者耐下心来 慢慢解决安装中出现的问题~MySQL 5.7 安装教程(全…...

《Django 5 By Example》阅读笔记:p455-p492

《Django 5 By Example》学习第 16 天,p455-p492 总结,总计 38 页。 一、技术总结 1.myshop (1)打折功能 使用折扣码实现,但是折扣码是手动生成的,感觉实际业务中应该不是这样的。 (2)推荐功能 使用 Redis 做缓存&#xff0…...

Element-UI 官网的主题切换动画

文章目录 实现圆形扩散过渡动画 实现一下 Element-UI 官网的主题切换动画加粗样式 实现 首先我们起一个 html 文件,写一个按钮,以及简单的背景颜色切换,来模拟主题的切换 想要实现过渡效果,需要先用到一个 JavaScript 的原生方…...

Golang 构建学习

Golang 构建学习 如何搭建Golang开发环境 1. 下载GOlang包 https://golang.google.cn/dl/ 在地址上下载Golang 2. 配置包环境 修改全局环境变量,GOPROXY,GOPATH,GOROOT GOPROXYhttps://goproxy.cn,direct GOROOT"" // go二进…...

VM Virutal Box的Ubuntu虚拟机与windows宿主机之间设置共享文件夹(自动挂载,永久有效)

本文参考如下链接 How to access a shared folder in VirtualBox? - Ask Ubuntu (1)安装增强功能(Guest Additions) 首先,在网上下载VBoxGuestAdditions光盘映像文件 下载地址:Index of http://…...

分析 系统滴答时钟(tickClock),设置72MHz系统周期,如何实现1毫秒的系统时间?

一、CubeMX相关配置 1.1 相关引脚配置 1.2 相关时钟数配置 1.3 打开程序源码 二、相关函数分析...

C++优选算法十七 多源BFS

1.单源最短路问题 一个起点一个终点。 定义:在给定加权图中,选择一个顶点作为源点,计算该源点到图中所有其他顶点的最短路径长度。 2.多源最短路问题 定义:多源最短路问题指的是在图中存在多个起点,需要求出从这些…...

Mongodb入门到放弃

Mongodb分片概括 分片在多台服务器上分布数据的方法, Mongodb使用分片来支持具有非常大的数据集和高吞吐量的操作的部署 具有大数据集和高吞吐量应用程序的数据库系统,可以挑战单台服务器的容量。 例如,高查询率可以耗尽服务器的cpu容量&…...

青藤云安全携手财信证券,入选金融科技创新应用优秀案例

11月29日,由中国信息通信研究院主办的第四届“金信通”金融科技创新应用案例评选结果正式发布。财信证券与青藤云安全联合提交的“基于RASP技术的API及数据链路安全治理项目”以其卓越的创新性和先进性,成功入选金融科技创新应用优秀案例。 据悉&#x…...

在CentOS系统中安装工具包的时候报错的解决方法

我刚装了一个新的虚拟机,打算安装一些工具出现了错误信息 执行的命令如下: yum install -y yum-utils device-mapper-persistent-data lvm2错误信息如下 Cannot find a valid baseurl for repo: base/7/x86_64搜索了一下原因有好几种。 一是网络不通…...

cad软件打不开报错cad acbrandres dll加载失败

一切本来很顺利哒 但是,当我用快捷方式打开时,就出现了这个错误。进入文件路径,是有这个的; 在文件路径直接打开,也会提示错误 原因竟然是我改了个名字: 随便选的文件路径,空的,文件名为Acr…...

14、保存与加载PyTorch训练的模型和超参数

文章目录 1. state_dict2. 模型保存3. check_point4. 详细保存5. Docker6. 机器学习常用库 1. state_dict nn.Module 类是所有神经网络构建的基类,即自己构建一个深度神经网络也是需要继承自nn.Module类才行,并且nn.Module中的state_dict包含神经网络中…...

【前端开发】JS+Vuew3请求列表数据并分页

应用技术:原生JavaScript Vue3 $(function () {ini(); });function ini() {const { createApp, ref, onMounted } Vue;createApp({setup() {const data ref({studentList: [],page: 1,pageSize: 10,});const getStudentList async (page, key) > {window.ons…...

Trimble X12助力电力管廊数据采集,为机器人巡视系统提供精准导航支持

地下电缆是一个城市重要的基础设施,它不仅具有规模大、范围广、空间分布复杂等特点,更重要的是它还承担着信息传输、能源输送等与人们生活息息相关的重要功能,也是一个城市赖以生存和发展的物质基础。 01、项目概述 本次项目是对某区域2公里左…...

Docker 清理镜像策略详解

文章目录 前言一、删除 Docker 镜像1. 查看当前镜像2. 删除单个镜像3. 删除多个镜像4. 删除所有未使用的镜像5. 删除悬空的 Docker 镜像6. 根据模式删除镜像7. 删除所有镜像 二、删除 Docker 容器1. 查找容器2. 删除一个或多个特定容器3. 退出时删除容器4. 删除所有已退出的容器…...

【Linux】TCP网络编程

目录 V1_Echo_Server V2_Echo_Server多进程版本 V3_Echo_Server多线程版本 V3-1_多线程远程命令执行 V4_Echo_Server线程池版本 V1_Echo_Server TcpServer的上层调用如下,和UdpServer几乎一样: 而在InitServer中,大部分也和UDP那里一样&…...

排序学习整理(2)

上集回顾 排序学习整理(1)-CSDN博客 2.3 交换排序 交换排序的基本思想是:根据序列中两个记录键值的比较结果,交换这两个记录在序列中的位置。 特点: 通过比较和交换操作,将键值较大的记录逐步移动到序列…...

AI蛋白质设计与人工智能药物设计

AI蛋白质设计与人工智能药物设计 AI蛋白质设计 一、蛋白质相关的深度学习简介 1.基础概念 1.1.机器学习简介:从手写数字识别到大语言模型 1.2.蛋白质结构预测与设计回顾 1.3.Linux简介 1.4.代码环境:VS code和Jupyter notebook* 1.5.Python关键概…...

IOS ARKit进行图像识别

先讲一下基础控涧,资源的话可以留言,抽空我把它传到GitHub上,这里没写收积分,竟然充值才能下载,我下载也要充值,牛! ARSCNView 可以理解画布或者场景 1 配置 ARWorldTrackingConfiguration AR追…...

初级数据结构——二叉搜索树

目录 前言一、定义二、基本操作三、时间复杂度分析四、变体五、动态图解六、代码模版七、经典例题[1.——700. 二叉搜索树中的搜索](https://leetcode.cn/problems/search-in-a-binary-search-tree/)代码题解 [2.——938. 二叉搜索树的范围和](https://leetcode.cn/problems/ra…...

C++设计模式之组合模式中如何实现同一层部件的有序性

在组合模式中,为了实现同一层上部件的有序性,可以采取以下几种设计方法: 1. 使用有序集合 使用有序集合(如 std::list、std::vector 或其他有序容器)来存储和管理子部件。这种方法可以确保子部件按照特定顺序排列&am…...

duxapp RN 端使用AppUpgrade 进行版本更新

版本更新包含了组件和工具的组合 注册 下面这是 duxcms 入口文件检查更新的注册方法,注册的同时会检查更新 import {request,updateApp,userConfig } from ./utils// 检查app更新 setTimeout(async () > {if (process.env.TARO_ENV rn) {// eslint-disable-n…...

【计网】自定义序列化反序列化(三) —— 实现网络版计算器【下】

🌎实现网络版计算器【下】 本次序列化与反序列化所用到的代码,Tcp服务自定义序列化反序列化实现网络版计算器。 文章目录: 实实现网络版计算器【下】 客户端实现     基于守护进程的改写 🚀客户端实现 在这之前&#xff0c…...

神经网络中的优化方法(一)

目录 摘要Abstract1. 与纯优化的区别1.1 经验风险最小化1.2 代理损失函数1.3 批量算法和小批量算法 2. 神经网络中优化的挑战2.1 病态2.2 局部极小值2.3 高原、鞍点和其他平坦区域2.4 悬崖和梯度爆炸2.5 长期依赖2.6 非精确梯度2.7 局部和全局结构间的弱对应 3. 基本算法3.1 随…...

Linux 计算机网络基础概念

目录 0.前言 1.计算机网络背景 1.1 独立模式 1.2 网络互联 1.3 局域网(Local Area Network,LAN) 1.4 广域网(Wide Area Network,WAN) 2.协议 2.1什么是协议 2.2协议分层和软件分层 2.3 OSI七层网络模型 2.3…...

qt QGraphicsEllipseItem详解

1、概述 QGraphicsEllipseItem是Qt框架中QGraphicsItem的一个子类,它提供了一个可以添加到QGraphicsScene中的椭圆项。QGraphicsEllipseItem表示一个带有填充和轮廓的椭圆,也可以用于表示椭圆段(通过startAngle()和spanAngle()方法&#xff…...

Python websocket

router.websocket(/chat/{flow_id}) 接口代码,并了解其工作流程、涉及的组件以及如何基于此实现你的新 WebSocket 接口。以下内容将分为几个部分进行讲解: 接口整体概述代码逐行解析关键组件和依赖关系如何基于此实现新功能示例:创建一个新的…...

【MySQL-5】MySQL的内置函数

目录 1. 整体学习的思维导图 2. 日期函数 ​编辑 2.1 current_date() 2.2 current_time() 2.3 current_timestamp() 2.4 date(datetime) 2.5 now() 2.6 date_add() 2.7 date_sub() 2.8 datediff() 2.9 案例 2.9.1 创建一个出生日期登记簿 2.9.2 创建一个留言版 3…...

深度学习笔记之BERT(三)RoBERTa

深度学习笔记之RoBERTa 引言回顾:BERT的预训练策略RoBERTa训练过程分析静态掩码与动态掩码的比较模型输入模式与下一句预测使用大批量进行训练使用Byte-pair Encoding作为子词词元化算法更大的数据集和更多的训练步骤 RoBERTa配置 引言 本节将介绍一种基于 BERT \t…...

海珠营销型网站建设/免费推广渠道有哪些

前两天刚刚装了一个MyEclipse,今天用了一下,却发现,每次想要在控制台上输出中文时,总是以乱码显示的。查了很多资料,对算是搞明白,怎么回事。首先,在这里先解释下,MyEclipse&#xf…...

wordpress 重写url插件/seo渠道

监听域对象的生命周期:在Web应用程序的运行期间,Web容器会创建和销毁三个比较重要的对象ServletContext、HttpSession和ServletRequest,这些对象被称为域对象,为了监听这些域对象的生命周期,Servlet API中专门提供三个…...

网站建设要什么知识/网店运营工资一般多少

快速了解K4B2G1646F-BYK0K4B2G1646F-BYK0组织为16Mbit x16 I / O x8 bank设备。对于一般应用,该同步器件可实现高达1866Mb / sec / pin(DDR3-1866)的高速双倍数据速率传输速率。该芯片的设计符合以下关键DDR3 SDRAM特性,例如发布的…...

建立网站准备工作/郑州手机网站建设

看到个好文章,翻译一遍分享一下。 此为https://go101.org/article/channel-closing.html的翻译,侵删。 文章目录怎么优雅地关闭通道通道的关闭原则简单粗暴的方案礼貌的方案优雅的方案更多场景?结论怎么优雅地关闭通道 许多天前,…...

低价企业网站搭建/9 1短视频安装

1 修改配置文件 /etc/my.conf (为了命令 mysqldump能省略输入密码执行,mysql5.5 之后已经不建议控制台直接输入密码的方式)增加如下配置[client]hostlocalhostuserrootpassword‘password‘2 创建任务 shell# !/bin/shdd"$(date "%Y%m%d%H%M%S")&qu…...

网站开发人员绩效如何计算/网络营销的理解

胡言乱语之gcc优化 本文为业余蒟蒻尝试分析一段简单的 C 代码在 gcc -O0、-O1、-O2 下的优化情况。 ______________ < 大佬驱散&#xff01;&#xff01; >--------------\ ^__^\ (oo)\___By___(__)\ CDFMLR )\/\||------||| ||做数值分析的实验&#xff0c;写了…...