1 // SPDX-License-Identifier: GPL-2.0
5 * Dong Aisheng <aisheng.dong@nxp.com>
9 #include <linux/clk-provider.h>
10 #include <linux/device.h>
11 #include <linux/export.h>
13 #include <linux/slab.h>
15 static int __must_check
of_clk_bulk_get(struct device_node
*np
, int num_clks
,
16 struct clk_bulk_data
*clks
)
21 for (i
= 0; i
< num_clks
; i
++) {
26 for (i
= 0; i
< num_clks
; i
++) {
27 of_property_read_string_index(np
, "clock-names", i
, &clks
[i
].id
);
28 clks
[i
].clk
= of_clk_get(np
, i
);
29 if (IS_ERR(clks
[i
].clk
)) {
30 ret
= PTR_ERR(clks
[i
].clk
);
31 pr_err("%pOF: Failed to get clk index: %d ret: %d\n",
41 clk_bulk_put(i
, clks
);
46 static int __must_check
of_clk_bulk_get_all(struct device_node
*np
,
47 struct clk_bulk_data
**clks
)
49 struct clk_bulk_data
*clk_bulk
;
53 num_clks
= of_clk_get_parent_count(np
);
57 clk_bulk
= kmalloc_array(num_clks
, sizeof(*clk_bulk
), GFP_KERNEL
);
61 ret
= of_clk_bulk_get(np
, num_clks
, clk_bulk
);
72 void clk_bulk_put(int num_clks
, struct clk_bulk_data
*clks
)
74 while (--num_clks
>= 0) {
75 clk_put(clks
[num_clks
].clk
);
76 clks
[num_clks
].clk
= NULL
;
79 EXPORT_SYMBOL_GPL(clk_bulk_put
);
81 static int __clk_bulk_get(struct device
*dev
, int num_clks
,
82 struct clk_bulk_data
*clks
, bool optional
)
87 for (i
= 0; i
< num_clks
; i
++)
90 for (i
= 0; i
< num_clks
; i
++) {
91 clks
[i
].clk
= clk_get(dev
, clks
[i
].id
);
92 if (IS_ERR(clks
[i
].clk
)) {
93 ret
= PTR_ERR(clks
[i
].clk
);
96 if (ret
== -ENOENT
&& optional
)
99 if (ret
!= -EPROBE_DEFER
)
100 dev_err(dev
, "Failed to get clk '%s': %d\n",
109 clk_bulk_put(i
, clks
);
114 int __must_check
clk_bulk_get(struct device
*dev
, int num_clks
,
115 struct clk_bulk_data
*clks
)
117 return __clk_bulk_get(dev
, num_clks
, clks
, false);
119 EXPORT_SYMBOL(clk_bulk_get
);
121 int __must_check
clk_bulk_get_optional(struct device
*dev
, int num_clks
,
122 struct clk_bulk_data
*clks
)
124 return __clk_bulk_get(dev
, num_clks
, clks
, true);
126 EXPORT_SYMBOL_GPL(clk_bulk_get_optional
);
128 void clk_bulk_put_all(int num_clks
, struct clk_bulk_data
*clks
)
130 if (IS_ERR_OR_NULL(clks
))
133 clk_bulk_put(num_clks
, clks
);
137 EXPORT_SYMBOL(clk_bulk_put_all
);
139 int __must_check
clk_bulk_get_all(struct device
*dev
,
140 struct clk_bulk_data
**clks
)
142 struct device_node
*np
= dev_of_node(dev
);
147 return of_clk_bulk_get_all(np
, clks
);
149 EXPORT_SYMBOL(clk_bulk_get_all
);
151 #ifdef CONFIG_HAVE_CLK_PREPARE
154 * clk_bulk_unprepare - undo preparation of a set of clock sources
155 * @num_clks: the number of clk_bulk_data
156 * @clks: the clk_bulk_data table being unprepared
158 * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable.
159 * Returns 0 on success, -EERROR otherwise.
161 void clk_bulk_unprepare(int num_clks
, const struct clk_bulk_data
*clks
)
163 while (--num_clks
>= 0)
164 clk_unprepare(clks
[num_clks
].clk
);
166 EXPORT_SYMBOL_GPL(clk_bulk_unprepare
);
169 * clk_bulk_prepare - prepare a set of clocks
170 * @num_clks: the number of clk_bulk_data
171 * @clks: the clk_bulk_data table being prepared
173 * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable.
174 * Returns 0 on success, -EERROR otherwise.
176 int __must_check
clk_bulk_prepare(int num_clks
,
177 const struct clk_bulk_data
*clks
)
182 for (i
= 0; i
< num_clks
; i
++) {
183 ret
= clk_prepare(clks
[i
].clk
);
185 pr_err("Failed to prepare clk '%s': %d\n",
194 clk_bulk_unprepare(i
, clks
);
198 EXPORT_SYMBOL_GPL(clk_bulk_prepare
);
200 #endif /* CONFIG_HAVE_CLK_PREPARE */
203 * clk_bulk_disable - gate a set of clocks
204 * @num_clks: the number of clk_bulk_data
205 * @clks: the clk_bulk_data table being gated
207 * clk_bulk_disable must not sleep, which differentiates it from
208 * clk_bulk_unprepare. clk_bulk_disable must be called before
209 * clk_bulk_unprepare.
211 void clk_bulk_disable(int num_clks
, const struct clk_bulk_data
*clks
)
214 while (--num_clks
>= 0)
215 clk_disable(clks
[num_clks
].clk
);
217 EXPORT_SYMBOL_GPL(clk_bulk_disable
);
220 * clk_bulk_enable - ungate a set of clocks
221 * @num_clks: the number of clk_bulk_data
222 * @clks: the clk_bulk_data table being ungated
224 * clk_bulk_enable must not sleep
225 * Returns 0 on success, -EERROR otherwise.
227 int __must_check
clk_bulk_enable(int num_clks
, const struct clk_bulk_data
*clks
)
232 for (i
= 0; i
< num_clks
; i
++) {
233 ret
= clk_enable(clks
[i
].clk
);
235 pr_err("Failed to enable clk '%s': %d\n",
244 clk_bulk_disable(i
, clks
);
248 EXPORT_SYMBOL_GPL(clk_bulk_enable
);