1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * KUnit helpers for clk providers and consumers
4 */
5 #include <linux/clk.h>
6 #include <linux/clk-provider.h>
7 #include <linux/err.h>
8 #include <linux/kernel.h>
9 #include <linux/slab.h>
10
11 #include <kunit/clk.h>
12 #include <kunit/resource.h>
13
14 KUNIT_DEFINE_ACTION_WRAPPER(clk_disable_unprepare_wrapper,
15 clk_disable_unprepare, struct clk *);
16 /**
17 * clk_prepare_enable_kunit() - Test managed clk_prepare_enable()
18 * @test: The test context
19 * @clk: clk to prepare and enable
20 *
21 * Return: 0 on success, or negative errno on failure.
22 */
clk_prepare_enable_kunit(struct kunit * test,struct clk * clk)23 int clk_prepare_enable_kunit(struct kunit *test, struct clk *clk)
24 {
25 int ret;
26
27 ret = clk_prepare_enable(clk);
28 if (ret)
29 return ret;
30
31 return kunit_add_action_or_reset(test, clk_disable_unprepare_wrapper,
32 clk);
33 }
34 EXPORT_SYMBOL_GPL(clk_prepare_enable_kunit);
35
36 KUNIT_DEFINE_ACTION_WRAPPER(clk_put_wrapper, clk_put, struct clk *);
37
__clk_get_kunit(struct kunit * test,struct clk * clk)38 static struct clk *__clk_get_kunit(struct kunit *test, struct clk *clk)
39 {
40 int ret;
41
42 if (IS_ERR(clk))
43 return clk;
44
45 ret = kunit_add_action_or_reset(test, clk_put_wrapper, clk);
46 if (ret)
47 return ERR_PTR(ret);
48
49 return clk;
50 }
51
52 /**
53 * clk_get_kunit() - Test managed clk_get()
54 * @test: The test context
55 * @dev: device for clock "consumer"
56 * @con_id: clock consumer ID
57 *
58 * Just like clk_get(), except the clk is managed by the test case and is
59 * automatically put with clk_put() after the test case concludes.
60 *
61 * Return: new clk consumer or ERR_PTR on failure.
62 */
63 struct clk *
clk_get_kunit(struct kunit * test,struct device * dev,const char * con_id)64 clk_get_kunit(struct kunit *test, struct device *dev, const char *con_id)
65 {
66 struct clk *clk;
67
68 clk = clk_get(dev, con_id);
69
70 return __clk_get_kunit(test, clk);
71 }
72 EXPORT_SYMBOL_GPL(clk_get_kunit);
73
74 /**
75 * of_clk_get_kunit() - Test managed of_clk_get()
76 * @test: The test context
77 * @np: device_node for clock "consumer"
78 * @index: index in 'clocks' property of @np
79 *
80 * Just like of_clk_get(), except the clk is managed by the test case and is
81 * automatically put with clk_put() after the test case concludes.
82 *
83 * Return: new clk consumer or ERR_PTR on failure.
84 */
85 struct clk *
of_clk_get_kunit(struct kunit * test,struct device_node * np,int index)86 of_clk_get_kunit(struct kunit *test, struct device_node *np, int index)
87 {
88 struct clk *clk;
89
90 clk = of_clk_get(np, index);
91
92 return __clk_get_kunit(test, clk);
93 }
94 EXPORT_SYMBOL_GPL(of_clk_get_kunit);
95
96 /**
97 * clk_hw_get_clk_kunit() - Test managed clk_hw_get_clk()
98 * @test: The test context
99 * @hw: clk_hw associated with the clk being consumed
100 * @con_id: connection ID string on device
101 *
102 * Just like clk_hw_get_clk(), except the clk is managed by the test case and
103 * is automatically put with clk_put() after the test case concludes.
104 *
105 * Return: new clk consumer or ERR_PTR on failure.
106 */
107 struct clk *
clk_hw_get_clk_kunit(struct kunit * test,struct clk_hw * hw,const char * con_id)108 clk_hw_get_clk_kunit(struct kunit *test, struct clk_hw *hw, const char *con_id)
109 {
110 struct clk *clk;
111
112 clk = clk_hw_get_clk(hw, con_id);
113
114 return __clk_get_kunit(test, clk);
115 }
116 EXPORT_SYMBOL_GPL(clk_hw_get_clk_kunit);
117
118 /**
119 * clk_hw_get_clk_prepared_enabled_kunit() - Test managed clk_hw_get_clk() + clk_prepare_enable()
120 * @test: The test context
121 * @hw: clk_hw associated with the clk being consumed
122 * @con_id: connection ID string on device
123 *
124 * Just like
125 *
126 * .. code-block:: c
127 *
128 * struct clk *clk = clk_hw_get_clk(...);
129 * clk_prepare_enable(clk);
130 *
131 * except the clk is managed by the test case and is automatically disabled and
132 * unprepared with clk_disable_unprepare() and put with clk_put() after the
133 * test case concludes.
134 *
135 * Return: new clk consumer that is prepared and enabled or ERR_PTR on failure.
136 */
137 struct clk *
clk_hw_get_clk_prepared_enabled_kunit(struct kunit * test,struct clk_hw * hw,const char * con_id)138 clk_hw_get_clk_prepared_enabled_kunit(struct kunit *test, struct clk_hw *hw,
139 const char *con_id)
140 {
141 int ret;
142 struct clk *clk;
143
144 clk = clk_hw_get_clk_kunit(test, hw, con_id);
145 if (IS_ERR(clk))
146 return clk;
147
148 ret = clk_prepare_enable_kunit(test, clk);
149 if (ret)
150 return ERR_PTR(ret);
151
152 return clk;
153 }
154 EXPORT_SYMBOL_GPL(clk_hw_get_clk_prepared_enabled_kunit);
155
156 KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_wrapper,
157 clk_hw_unregister, struct clk_hw *);
158
159 /**
160 * clk_hw_register_kunit() - Test managed clk_hw_register()
161 * @test: The test context
162 * @dev: device that is registering this clock
163 * @hw: link to hardware-specific clock data
164 *
165 * Just like clk_hw_register(), except the clk registration is managed by the
166 * test case and is automatically unregistered after the test case concludes.
167 *
168 * Return: 0 on success or a negative errno value on failure.
169 */
clk_hw_register_kunit(struct kunit * test,struct device * dev,struct clk_hw * hw)170 int clk_hw_register_kunit(struct kunit *test, struct device *dev, struct clk_hw *hw)
171 {
172 int ret;
173
174 ret = clk_hw_register(dev, hw);
175 if (ret)
176 return ret;
177
178 return kunit_add_action_or_reset(test, clk_hw_unregister_wrapper, hw);
179 }
180 EXPORT_SYMBOL_GPL(clk_hw_register_kunit);
181
182 /**
183 * of_clk_hw_register_kunit() - Test managed of_clk_hw_register()
184 * @test: The test context
185 * @node: device_node of device that is registering this clock
186 * @hw: link to hardware-specific clock data
187 *
188 * Just like of_clk_hw_register(), except the clk registration is managed by
189 * the test case and is automatically unregistered after the test case
190 * concludes.
191 *
192 * Return: 0 on success or a negative errno value on failure.
193 */
of_clk_hw_register_kunit(struct kunit * test,struct device_node * node,struct clk_hw * hw)194 int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, struct clk_hw *hw)
195 {
196 int ret;
197
198 ret = of_clk_hw_register(node, hw);
199 if (ret)
200 return ret;
201
202 return kunit_add_action_or_reset(test, clk_hw_unregister_wrapper, hw);
203 }
204 EXPORT_SYMBOL_GPL(of_clk_hw_register_kunit);
205
206 MODULE_LICENSE("GPL");
207 MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers");
208