news 2026/4/16 18:12:51

[Linux]学习笔记系列 -- [drivers][clk]clk-bulk

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[Linux]学习笔记系列 -- [drivers][clk]clk-bulk

title: clk-bulk
categories:

  • linux
  • drivers
  • clk
    tags:
  • linux
  • drivers
  • clk
    abbrlink: fc0f43c4
    date: 2025-10-03 09:01:49

https://github.com/wdfk-prog/linux-study

文章目录

  • drivers/clk/clk-bulk.c 批量时钟控制(Bulk Clock Control) 简化多路时钟管理
      • 历史与背景
        • 这项技术是为了解决什么特定问题而诞生的?
        • 它的发展经历了哪些重要的里程碑或版本迭代?
        • 目前该技术的社区活跃度和主流应用情况如何?
      • 核心原理与设计
        • 它的核心工作原理是什么?
        • 它的主要优势体现在哪些方面?
        • 它存在哪些已知的劣势、局限性或在特定场景下的不适用性?
      • 使用场景
        • 在哪些具体的业务或技术场景下,它是首选解决方案?请例举说明。
        • 是否有不推荐使用该技术的场景?为什么?
      • 对比分析
        • 请将其 与 其他相似技术 进行详细对比。
    • clk_bulk_prepare
    • clk_bulk_enable

drivers/clk/clk-bulk.c 批量时钟控制(Bulk Clock Control) 简化多路时钟管理

历史与背景

这项技术是为了解决什么特定问题而诞生的?

drivers/clk/clk-bulk.c文件实现了一套批量时钟控制的辅助API。这项技术并非一个独立的框架,而是对通用时钟框架(Common Clock Framework, CCF)的一个重要补充和优化。它的诞生是为了解决设备驱动程序中管理多个时钟资源时的代码冗余、逻辑复杂和易于出错的问题。

许多现代SoC中的复杂外设(如显示控制器、GPU、视频处理器)往往不只依赖一个时钟,而是需要一组时钟(例如,一个像素时钟、一个总线接口时钟、一个寄存器访问时钟)同时被使能才能正常工作。在没有clk-bulkAPI之前,驱动程序必须:

  1. 逐个调用devm_clk_get()来获取每一个时钟的句柄。
  2. 编写一个循环来逐个调用clk_prepare_enable()来使能这些时钟。
  3. 最关键也是最麻烦的是,必须编写复杂的错误处理代码。如果在使能第五个时钟时失败了,驱动程序必须手动地、按相反的顺序去clk_disable_unprepare()前四个已经成功使能的时钟,以保证系统状态的一致性。

这种手动管理模式导致驱动的.probe()函数中充满了重复的、冗长的、极易出错的样板代码。clk-bulkAPI的诞生就是为了将这种“获取一组资源,要么全部成功,要么全部回滚”的事务性操作抽象成一个简单的函数调用。

它的发展经历了哪些重要的里程碑或版本迭代?

clk-bulkAPI是随着CCF的成熟和SoC复杂度的增加而自然演进出来的辅助功能。

  • 模式识别:内核开发者们在审查大量复杂驱动(特别是DRM图形驱动和多媒体驱动)时,发现上述手动管理多个时钟的模式被反复实现。
  • API抽象:为了消除这种重复,社区将这种通用模式抽象出来,创建了clk-bulkAPI,提供了clk_bulk_get,clk_bulk_prepare_enable,clk_bulk_disable_unprepare等核心函数。
  • devm集成:为了与设备资源管理(devres)框架更好地集成,后续又添加了devm_clk_bulk_getdevm_clk_bulk_get_all等函数,使得时钟句柄的获取也能被devres自动管理,进一步简化了驱动的资源释放逻辑。
目前该技术的社区活跃度和主流应用情况如何?

clk-bulkAPI已经成为CCF中一个非常标准和成熟的部分,是编写需要管理多个时钟的驱动时的最佳实践。它被广泛应用于内核中各种复杂的驱动程序,尤其是:

  • DRM(Direct Rendering Manager)图形和显示驱动
  • V4L2(Video for Linux 2)多媒体驱动(如视频编解码器、ISP)
  • SoC平台驱动中用于管理复杂IP核的驱动

核心原理与设计

它的核心工作原理是什么?

clk-bulk的核心原理非常直接:它将针对单个时钟的操作封装在一个循环中,并内置了健壮的错误处理和回滚(unwind)逻辑。

  1. 批量获取(Bulk Get)

    • 驱动程序通常在设备树中通过clock-names属性列出所有需要的时钟名。
    • 驱动调用devm_clk_bulk_get_all(dev, &clks)
    • 这个函数会解析clock-names属性,并在内部循环调用devm_clk_get()来获取每一个时钟的句柄,然后将这些句柄填充到一个由调用者提供的数组中。
  2. 批量使能(Bulk Enable)

    • 驱动调用clk_bulk_prepare_enable(num_clocks, clks)
    • 这个函数内部会启动一个循环,按顺序对数组中的每一个时钟调用clk_prepare_enable()
    • 关键的回滚逻辑:如果在循环过程中,有任何一个clk_prepare_enable()调用失败并返回错误,该函数会立即停止。然后,它会自动启动另一个循环,按相反的顺序对所有已经成功使能的时钟调用clk_disable_unprepare(),从而将时钟状态回滚到调用之前的状态。最后,它将原始的错误码返回给调用者。
  3. 批量禁用(Bulk Disable)

    • 驱动调用clk_bulk_disable_unprepare(num_clocks, clks)
    • 这个函数简单地按相反顺序循环遍历时钟数组,并对每个时钟调用clk_disable_unprepare()
它的主要优势体现在哪些方面?
  • 代码极大简化:将几十行复杂的、带错误处理的循环代码,缩减为一两个函数调用。
  • 健壮性:将容易出错的回滚逻辑集中在一个地方实现并经过充分测试,极大地提高了驱动程序的健壮性,避免了开发者因疏忽而导致的资源泄漏或状态不一致。
  • 可读性:驱动代码的意图变得更加清晰。clk_bulk_prepare_enable明确地表达了“将这一组时钟作为一个整体进行使能”的意图。
它存在哪些已知的劣势、局限性或在特定场景下的不适用性?
  • 缺乏个性化操作clk-bulkAPI将所有时钟视为一个同质的集合,统一进行使能或禁用。它不提供对组内单个时钟进行独立操作(如单独设置某个时钟的频率)的接口。如果需要这类操作,驱动仍然需要获取单个时钟的句柄并调用标准的clk_*API。
  • “全体一致”模型:该API适用于所有时钟需要被同时打开或关闭的场景。如果一组时钟有不同的生命周期(例如,时钟A需要一直开启,而时钟B仅在特定操作时开启),那么它们就不应该被放在同一个批量操作中。

使用场景

在哪些具体的业务或技术场景下,它是首选解决方案?请例举说明。

clk-bulk是任何**一个设备驱动需要依赖两个或更多时钟,并且这些时钟的生命周期一致(需要同时开启和关闭)**时的首选解决方案。

  • 场景一:DRM显示控制器驱动
    一个显示控制器(CRTC)可能需要一个bus_clk来访问寄存器,一个axi_clk来进行内存访问,以及一个pixel_clk来驱动显示面板。这三个时钟必须全部开启,显示通路才能工作。驱动程序会在.enable()回调中调用clk_bulk_prepare_enable(),在.disable()回调中调用clk_bulk_disable_unprepare()
  • 场景二:视频解码器驱动
    一个H.264硬件解码器可能需要一个core_clk用于其主逻辑,一个mem_clk用于访问帧缓冲,以及一个reg_clk用于CPU访问。这些时钟也构成了一个必须被整体管理的集合。
  • 场景三:复杂的SoC外设
    一个集成了SPI主控和DMA引擎的IP核,可能需要spi_clkdma_clk。如果驱动的设计是让它们协同工作,那么使用clk-bulkAPI来管理这两个时钟会非常方便。
是否有不推荐使用该技术的场景?为什么?
  • 单时钟设备:如果一个设备只需要一个时钟,使用clk-bulkAPI纯属画蛇添足,标准的devm_clk_get()clk_prepare_enable()更简单直接。
  • 生命周期不同的多时钟设备:如果一个设备有多个时钟,但它们的开关时机不同。例如,一个bus_clk需要在整个驱动生命周期内保持开启,而一个高功耗的core_clk仅在执行计算密集型任务时才被短暂开启。这种情况下,这两个时钟必须被独立管理。

对比分析

请将其 与 其他相似技术 进行详细对比。

clk-bulkAPI的主要对比对象就是不使用它,而是手动实现相同逻辑的“DIY”方法。

特性clk-bulkAPI手动循环管理
实现方式调用devm_clk_bulk_get_all()clk_bulk_prepare_enable()等高级API。在驱动中编写for循环,逐个调用devm_clk_get()clk_prepare_enable()
代码复杂度极低。几行代码即可完成。。需要编写获取、使能、错误检查和错误回滚的完整逻辑,代码量大且嵌套深。
健壮性。核心的回滚逻辑是标准化的、经过充分测试的。中到低。每个驱动的实现质量参差不齐,极易在回滚逻辑中引入bug。
可读性和维护性。代码简洁,意图清晰。。大量的样板代码掩盖了驱动的核心逻辑,难以阅读和维护。
开发效率。开发者无需花费时间在重复的、易错的基础设施代码上。。需要为每个驱动编写和调试相同的底层逻辑。
功能提供一个“全有或全无”的事务性保证。功能取决于开发者的实现,但通常目标是实现与clk-bulk相同的功能。

clk_bulk_prepare

/** * clk_bulk_prepare - prepare a set of clocks * @num_clks: the number of clk_bulk_data * @clks: the clk_bulk_data table being prepared * * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable. * Returns 0 on success, -EERROR otherwise. */int__must_checkclk_bulk_prepare(intnum_clks,conststructclk_bulk_data*clks){intret;inti;for(i=0;i<num_clks;i++){ret=clk_prepare(clks[i].clk);if(ret){pr_err("Failed to prepare clk '%s': %d\n",clks[i].id,ret);gotoerr;}}return0;err:clk_bulk_unprepare(i,clks);returnret;}EXPORT_SYMBOL_GPL(clk_bulk_prepare);

clk_bulk_enable

/** * clk_bulk_enable - ungate a set of clocks * @num_clks: the number of clk_bulk_data * @clks: the clk_bulk_data table being ungated * * clk_bulk_enable must not sleep * Returns 0 on success, -EERROR otherwise. */int__must_checkclk_bulk_enable(intnum_clks,conststructclk_bulk_data*clks){intret;inti;for(i=0;i<num_clks;i++){ret=clk_enable(clks[i].clk);if(ret){pr_err("Failed to enable clk '%s': %d\n",clks[i].id,ret);gotoerr;}}return0;err:clk_bulk_disable(i,clks);returnret;}EXPORT_SYMBOL_GPL(clk_bulk_enable);
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 16:07:47

动手实测YOLOv13:三行代码实现高精度目标识别

动手实测YOLOv13&#xff1a;三行代码实现高精度目标识别 在智慧物流分拣中心的高速传送带上&#xff0c;每分钟经过200件包裹&#xff0c;传统检测系统面对叠放、反光、遮挡等复杂工况频频漏检&#xff1b;而在城市交通监控大屏前&#xff0c;暴雨夜中模糊的车牌与低光照下的…

作者头像 李华
网站建设 2026/4/15 17:41:44

智能家居中i2s音频接口设计:完整指南

以下是对您提供的博文《智能家居中I2S音频接口设计&#xff1a;完整技术分析指南》的 深度润色与专业重构版本 。本次优化严格遵循您的全部要求&#xff1a; ✅ 彻底去除AI痕迹&#xff0c;语言自然、有“人味”——像一位十年嵌入式音频系统工程师在技术分享会上娓娓道来&a…

作者头像 李华
网站建设 2026/4/16 15:55:13

电商推荐系统实战:用PyTorch-2.x-Universal-Dev-v1.0快速实现模型训练

电商推荐系统实战&#xff1a;用PyTorch-2.x-Universal-Dev-v1.0快速实现模型训练 1. 为什么电商推荐系统值得你花10分钟上手 你有没有想过&#xff0c;当用户在电商平台上浏览商品时&#xff0c;那些精准出现在首页的“猜你喜欢”、购物车页面的“买了又买”、结算页的“搭配…

作者头像 李华
网站建设 2026/4/16 9:05:04

如何优化YOLOE推理速度?几个实用技巧分享

如何优化YOLOE推理速度&#xff1f;几个实用技巧分享 YOLOE&#xff08;Real-Time Seeing Anything&#xff09;作为新一代开放词汇目标检测与分割模型&#xff0c;以“零样本迁移实时推理”双优势迅速在工业场景中崭露头角。但很多工程师在实际部署时发现&#xff1a;明明文档…

作者头像 李华
网站建设 2026/4/16 15:54:59

轻量嵌入模型怎么选?Qwen3-Embedding-0.6B给出答案

轻量嵌入模型怎么选&#xff1f;Qwen3-Embedding-0.6B给出答案 1. 为什么轻量嵌入模型正在成为新刚需&#xff1f; 你有没有遇到过这样的情况&#xff1a; 想给一个中小规模知识库快速配上语义搜索&#xff0c;但发现8B模型在4卡A10上跑得吃力&#xff0c;显存占用超95%&…

作者头像 李华
网站建设 2026/4/16 14:28:20

零基础也能用!BSHM人像抠图镜像一键部署,实测效果惊艳

零基础也能用&#xff01;BSHM人像抠图镜像一键部署&#xff0c;实测效果惊艳 你是不是也遇到过这些情况&#xff1a; 想给产品图换背景&#xff0c;但PS抠图太费时间&#xff1b; 做短视频需要透明人像&#xff0c;可专业软件学不会&#xff1b; 设计师朋友说“这个边缘要精细…

作者头像 李华