Linux中clk_get与of_clk_get的区别及使用逻辑确认
关于clk_get和of_clk_get的工作方式验证
核心结论
你的理解完全正确,这两种时钟获取方式都基于设备树信息,只是选择时钟的维度不同。
具体细节说明
clk_get(及devm_clk_get)的工作逻辑
- 它通过设备树中设备节点的
clock-names属性匹配时钟:驱动传入的名称(比如代码里的"refclk")会和设备节点的clock-names列表中的字符串一一对应,找到后绑定到clocks属性中对应位置的时钟句柄。 - 对应你提供的设备树片段,
uart0节点的clock-names = "refclk"和clocks = <&periph_clk>是一一对应的,所以clk_get(&pdev->dev, "refclk")会直接拿到periph_clk这个时钟。
- 它通过设备树中设备节点的
of_clk_get的工作逻辑
- 它通过时钟输入说明符的索引ID选择时钟:索引从0开始,对应设备节点
clocks属性中时钟句柄的顺序。比如代码里的of_clk_get(pdev->dev.of_node, 0),就是取clocks列表里的第一个时钟(也就是<&periph_clk>)。
- 它通过时钟输入说明符的索引ID选择时钟:索引从0开始,对应设备节点
驱动代码的容错逻辑
你看到的bcm63xx_uart.c中的代码是典型的兼容处理:clk = clk_get(&pdev->dev, "refclk"); // first try if (IS_ERR(clk) && pdev->dev.of_node) clk = of_clk_get(pdev->dev.of_node, 0); // second try先尝试更清晰的按名称匹配(可读性更好,也更不容易出错),如果失败(比如某些旧设备树没有定义
clock-names),就降级到按索引取第一个时钟,保证驱动能适配不同的设备树写法。
补充说明
- devm_clk_get和clk_get的核心区别是资源托管:devm_开头的函数会把获取到的时钟资源和设备对象绑定,设备销毁时自动释放,不需要手动调用clk_put;而clk_get需要手动管理释放。
- 你参考的资料里提到的"托管资源时钟"和"非托管资源时钟",本质就是资源管理方式的差异,和时钟选择逻辑无关。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

