如何从设备树节点获取时钟

how to get a clock from a device tree node

我有以下问题:我想定义时钟 a CPU 应该在设备树中而不是在时钟驱动程序代码中的频率转换期间使用(这样它会更通用)。我想在设备树中定义 "transition-clock" 属性,比如:

 232         cpu: cpu@01c20050 {
 233             #clock-cells = <0>;
 234             compatible = "allwinner,sun4i-a10-cpu-clk";
 235             reg = <0x01c20050 0x4>;
-----
 243             clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
 244             transition-clock = <&osc24M>;
 245             clock-output-names = "cpu";
 246         };

我更改了文件 "drivers/clk/clkdev.c" 来搜索这个 属性 这样我就可以获得一个 clk 指针并将其存储在 cpu 时钟结构中的新 属性 中。这是我到目前为止所管理的(更改从第 78 行开始):

 59 static struct clk *__of_clk_get(struct device_node *np, int index,
 60                    const char *dev_id, const char *con_id)
 61 {
 62     struct of_phandle_args clkspec;
 63     struct clk *clk, *transition_clk;
 64     struct device_node *clock_node, *transition_clock_node;
 65     int rc;
 66     
 67     if (index < 0)
 68         return ERR_PTR(-EINVAL);
 69         
 70     rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
 71                     &clkspec);
 72     if (rc)         
 73         return ERR_PTR(rc);
 74         
 75     clk = __of_clk_get_by_clkspec(&clkspec, dev_id, con_id);
 76     of_node_put(clkspec.np);
 77     
 78     clock_node = of_parse_phandle(np, "clocks", 0);
 79     pr_err("-------------------- parsing node %s\n", np->name);
 80     if (clock_node!=NULL) {
 81         pr_err("============ Clock node found %p\n", clock_node);
 82         transition_clock_node =
 83             of_parse_phandle(clock_node, "transition-clock", 0);
 84         if (transition_clock_node!=NULL) {
 85             pr_err("============ Transition clock node found %p\n",
 86                 transition_clock_node);
 87             transition_clk = clk_get(clock_node, 0);
 88             pr_err("============ Transition clock %p\n", transition_clk);
 89         }
 90     }
 91     
 92     return clk;
 93 }

我得到指向时钟节点和转换时钟节点的指针,但是当我尝试从中获取时钟指针时,我得到 0xfffffffe,这看起来像一个错误:

[    2.540542] -------------------- parsing node cpu
[    2.540546] ============ Clock node found eeef9520
[    2.540550] ============ Transition clock node found eeef8934
[    2.540555] ============ Transition clock fffffffe

我想要一个时钟对象,以后可以在

中使用
clk_set_parent(cpu_clk, cpu_clk->transition_clk)

欢迎提出任何想法:)

好的,我同时弄明白了,因为没有人回答我将提供我的解决方案(也许其他人遇到了这个问题):

 81     if (clock_node != NULL) {
 82         rc = of_parse_phandle_with_args(clock_node, "transition-clock", NULL,
 83             0, &transition_clkspec);
 84         of_node_put(transition_clkspec.np);
 85 
 86         if (!rc) {
 87             transition_clock = __of_clk_get_by_clkspec(&transition_clkspec,
 88                 dev_id, con_id);
 89             clk_set_transition_parent(clk, transition_clock);
 90         }
 91     }

因此,解决方案是获取类型为 "of_phandle_args" 的对象,然后使用 __of_clk_get_by_clkspec 从那里获取时钟。

(clk_set_transition_parent 函数在其他地方定义,它的功能完全符合其名称的含义)