如何从设备树节点获取时钟
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 函数在其他地方定义,它的功能完全符合其名称的含义)
我有以下问题:我想定义时钟 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 函数在其他地方定义,它的功能完全符合其名称的含义)