xref: /linux/drivers/clk/clk-fixed-rate_test.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * KUnit test for clk fixed rate basic type
4  */
5 #include <linux/clk.h>
6 #include <linux/clk-provider.h>
7 #include <linux/completion.h>
8 #include <linux/of.h>
9 #include <linux/platform_device.h>
10 
11 #include <kunit/clk.h>
12 #include <kunit/of.h>
13 #include <kunit/platform_device.h>
14 #include <kunit/resource.h>
15 #include <kunit/test.h>
16 
17 #include "clk-fixed-rate_test.h"
18 
19 /**
20  * struct clk_hw_fixed_rate_kunit_params - Parameters to pass to __clk_hw_register_fixed_rate()
21  * @dev: device registering clk
22  * @np: device_node of device registering clk
23  * @name: name of clk
24  * @parent_name: parent name of clk
25  * @parent_hw: clk_hw pointer to parent of clk
26  * @parent_data: parent_data describing parent of clk
27  * @flags: clk framework flags
28  * @fixed_rate: frequency of clk
29  * @fixed_accuracy: accuracy of clk
30  * @clk_fixed_flags: fixed rate specific clk flags
31  */
32 struct clk_hw_fixed_rate_kunit_params {
33 	struct device *dev;
34 	struct device_node *np;
35 	const char *name;
36 	const char *parent_name;
37 	const struct clk_hw *parent_hw;
38 	const struct clk_parent_data *parent_data;
39 	unsigned long flags;
40 	unsigned long fixed_rate;
41 	unsigned long fixed_accuracy;
42 	unsigned long clk_fixed_flags;
43 };
44 
45 static int
clk_hw_register_fixed_rate_kunit_init(struct kunit_resource * res,void * context)46 clk_hw_register_fixed_rate_kunit_init(struct kunit_resource *res, void *context)
47 {
48 	struct clk_hw_fixed_rate_kunit_params *params = context;
49 	struct clk_hw *hw;
50 
51 	hw = __clk_hw_register_fixed_rate(params->dev, params->np,
52 					  params->name,
53 					  params->parent_name,
54 					  params->parent_hw,
55 					  params->parent_data,
56 					  params->flags,
57 					  params->fixed_rate,
58 					  params->fixed_accuracy,
59 					  params->clk_fixed_flags,
60 					  false);
61 	if (IS_ERR(hw))
62 		return PTR_ERR(hw);
63 
64 	res->data = hw;
65 
66 	return 0;
67 }
68 
clk_hw_register_fixed_rate_kunit_exit(struct kunit_resource * res)69 static void clk_hw_register_fixed_rate_kunit_exit(struct kunit_resource *res)
70 {
71 	struct clk_hw *hw = res->data;
72 
73 	clk_hw_unregister_fixed_rate(hw);
74 }
75 
76 /**
77  * clk_hw_register_fixed_rate_kunit() - Test managed __clk_hw_register_fixed_rate()
78  * @test: The test context
79  * @params: Arguments to __clk_hw_register_fixed_rate()
80  *
81  * Return: Registered fixed rate clk_hw or ERR_PTR on failure
82  */
83 static struct clk_hw *
clk_hw_register_fixed_rate_kunit(struct kunit * test,struct clk_hw_fixed_rate_kunit_params * params)84 clk_hw_register_fixed_rate_kunit(struct kunit *test,
85 				 struct clk_hw_fixed_rate_kunit_params *params)
86 {
87 	struct clk_hw *hw;
88 
89 	hw = kunit_alloc_resource(test,
90 				  clk_hw_register_fixed_rate_kunit_init,
91 				  clk_hw_register_fixed_rate_kunit_exit,
92 				  GFP_KERNEL, params);
93 	if (!hw)
94 		return ERR_PTR(-EINVAL);
95 
96 	return hw;
97 }
98 
99 /**
100  * clk_hw_unregister_fixed_rate_kunit() - Test managed clk_hw_unregister_fixed_rate()
101  * @test: The test context
102  * @hw: fixed rate clk to unregister upon test completion
103  *
104  * Automatically unregister @hw when @test is complete via
105  * clk_hw_unregister_fixed_rate().
106  *
107  * Return: 0 on success or negative errno on failure
108  */
clk_hw_unregister_fixed_rate_kunit(struct kunit * test,struct clk_hw * hw)109 static int clk_hw_unregister_fixed_rate_kunit(struct kunit *test, struct clk_hw *hw)
110 {
111 	if (!kunit_alloc_resource(test, NULL,
112 				  clk_hw_register_fixed_rate_kunit_exit,
113 				  GFP_KERNEL, hw))
114 		return -ENOMEM;
115 
116 	return 0;
117 }
118 
119 /*
120  * Test that clk_get_rate() on a fixed rate clk registered with
121  * clk_hw_register_fixed_rate() gets the proper frequency.
122  */
clk_fixed_rate_rate_test(struct kunit * test)123 static void clk_fixed_rate_rate_test(struct kunit *test)
124 {
125 	struct clk_hw *hw;
126 	struct clk *clk;
127 	const unsigned long fixed_rate = 230000;
128 
129 	hw = clk_hw_register_fixed_rate(NULL, "test-fixed-rate", NULL, 0, fixed_rate);
130 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
131 	KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
132 
133 	clk = clk_hw_get_clk_prepared_enabled_kunit(test, hw, __func__);
134 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
135 
136 	KUNIT_EXPECT_EQ(test, fixed_rate, clk_get_rate(clk));
137 }
138 
139 /*
140  * Test that clk_get_accuracy() on a fixed rate clk registered via
141  * clk_hw_register_fixed_rate_with_accuracy() gets the proper accuracy.
142  */
clk_fixed_rate_accuracy_test(struct kunit * test)143 static void clk_fixed_rate_accuracy_test(struct kunit *test)
144 {
145 	struct clk_hw *hw;
146 	struct clk *clk;
147 	const unsigned long fixed_accuracy = 5000;
148 
149 	hw = clk_hw_register_fixed_rate_with_accuracy(NULL, "test-fixed-rate",
150 						      NULL, 0, 0,
151 						      fixed_accuracy);
152 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
153 	KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
154 
155 	clk = clk_hw_get_clk_kunit(test, hw, __func__);
156 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
157 
158 	KUNIT_EXPECT_EQ(test, fixed_accuracy, clk_get_accuracy(clk));
159 }
160 
161 /* Test suite for a fixed rate clk without any parent */
162 static struct kunit_case clk_fixed_rate_test_cases[] = {
163 	KUNIT_CASE(clk_fixed_rate_rate_test),
164 	KUNIT_CASE(clk_fixed_rate_accuracy_test),
165 	{}
166 };
167 
168 static struct kunit_suite clk_fixed_rate_suite = {
169 	.name = "clk_fixed_rate",
170 	.test_cases = clk_fixed_rate_test_cases,
171 };
172 
173 /*
174  * Test that clk_get_parent() on a fixed rate clk gets the proper parent.
175  */
clk_fixed_rate_parent_test(struct kunit * test)176 static void clk_fixed_rate_parent_test(struct kunit *test)
177 {
178 	struct clk_hw *hw, *parent_hw;
179 	struct clk *expected_parent, *actual_parent;
180 	struct clk *clk;
181 	const char *parent_name = "test-fixed-rate-parent";
182 	struct clk_hw_fixed_rate_kunit_params parent_params = {
183 		.name = parent_name,
184 	};
185 
186 	parent_hw = clk_hw_register_fixed_rate_kunit(test, &parent_params);
187 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
188 	KUNIT_ASSERT_STREQ(test, parent_name, clk_hw_get_name(parent_hw));
189 
190 	expected_parent = clk_hw_get_clk_kunit(test, parent_hw, __func__);
191 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_parent);
192 
193 	hw = clk_hw_register_fixed_rate(NULL, "test-fixed-rate", parent_name, 0, 0);
194 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
195 	KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
196 
197 	clk = clk_hw_get_clk_kunit(test, hw, __func__);
198 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
199 
200 	actual_parent = clk_get_parent(clk);
201 	KUNIT_EXPECT_TRUE(test, clk_is_match(expected_parent, actual_parent));
202 }
203 
204 /*
205  * Test that clk_get_rate() on a fixed rate clk ignores the parent rate.
206  */
clk_fixed_rate_parent_rate_test(struct kunit * test)207 static void clk_fixed_rate_parent_rate_test(struct kunit *test)
208 {
209 	struct clk_hw *hw, *parent_hw;
210 	struct clk *clk;
211 	const unsigned long expected_rate = 1405;
212 	const unsigned long parent_rate = 90402;
213 	const char *parent_name = "test-fixed-rate-parent";
214 	struct clk_hw_fixed_rate_kunit_params parent_params = {
215 		.name = parent_name,
216 		.fixed_rate = parent_rate,
217 	};
218 
219 	parent_hw = clk_hw_register_fixed_rate_kunit(test, &parent_params);
220 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
221 	KUNIT_ASSERT_STREQ(test, parent_name, clk_hw_get_name(parent_hw));
222 
223 	hw = clk_hw_register_fixed_rate(NULL, "test-fixed-rate", parent_name, 0,
224 					expected_rate);
225 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
226 	KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
227 
228 	clk = clk_hw_get_clk_prepared_enabled_kunit(test, hw, __func__);
229 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
230 
231 	KUNIT_EXPECT_EQ(test, expected_rate, clk_get_rate(clk));
232 }
233 
234 /*
235  * Test that clk_get_accuracy() on a fixed rate clk ignores the parent accuracy.
236  */
clk_fixed_rate_parent_accuracy_test(struct kunit * test)237 static void clk_fixed_rate_parent_accuracy_test(struct kunit *test)
238 {
239 	struct clk_hw *hw, *parent_hw;
240 	struct clk *clk;
241 	const unsigned long expected_accuracy = 900;
242 	const unsigned long parent_accuracy = 24000;
243 	const char *parent_name = "test-fixed-rate-parent";
244 	struct clk_hw_fixed_rate_kunit_params parent_params = {
245 		.name = parent_name,
246 		.fixed_accuracy = parent_accuracy,
247 	};
248 
249 	parent_hw = clk_hw_register_fixed_rate_kunit(test, &parent_params);
250 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
251 	KUNIT_ASSERT_STREQ(test, parent_name, clk_hw_get_name(parent_hw));
252 
253 	hw = clk_hw_register_fixed_rate_with_accuracy(NULL, "test-fixed-rate",
254 						      parent_name, 0, 0,
255 						      expected_accuracy);
256 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
257 	KUNIT_ASSERT_EQ(test, 0, clk_hw_unregister_fixed_rate_kunit(test, hw));
258 
259 	clk = clk_hw_get_clk_kunit(test, hw, __func__);
260 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
261 
262 	KUNIT_EXPECT_EQ(test, expected_accuracy, clk_get_accuracy(clk));
263 }
264 
265 /* Test suite for a fixed rate clk with a parent */
266 static struct kunit_case clk_fixed_rate_parent_test_cases[] = {
267 	KUNIT_CASE(clk_fixed_rate_parent_test),
268 	KUNIT_CASE(clk_fixed_rate_parent_rate_test),
269 	KUNIT_CASE(clk_fixed_rate_parent_accuracy_test),
270 	{}
271 };
272 
273 static struct kunit_suite clk_fixed_rate_parent_suite = {
274 	.name = "clk_fixed_rate_parent",
275 	.test_cases = clk_fixed_rate_parent_test_cases,
276 };
277 
278 struct clk_fixed_rate_of_test_context {
279 	struct device *dev;
280 	struct platform_driver pdrv;
281 	struct completion probed;
282 };
283 
284 static inline struct clk_fixed_rate_of_test_context *
pdev_to_clk_fixed_rate_of_test_context(struct platform_device * pdev)285 pdev_to_clk_fixed_rate_of_test_context(struct platform_device *pdev)
286 {
287 	return container_of(to_platform_driver(pdev->dev.driver),
288 			    struct clk_fixed_rate_of_test_context,
289 			    pdrv);
290 }
291 
292 /*
293  * Test that of_fixed_clk_setup() registers a fixed rate clk with the proper
294  * rate.
295  */
clk_fixed_rate_of_probe_test(struct kunit * test)296 static void clk_fixed_rate_of_probe_test(struct kunit *test)
297 {
298 	struct clk_fixed_rate_of_test_context *ctx = test->priv;
299 	struct device *dev = ctx->dev;
300 	struct clk *clk;
301 
302 	clk = clk_get_kunit(test, dev, NULL);
303 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
304 
305 	KUNIT_ASSERT_EQ(test, 0, clk_prepare_enable_kunit(test, clk));
306 	KUNIT_EXPECT_EQ(test, TEST_FIXED_FREQUENCY, clk_get_rate(clk));
307 }
308 
309 /*
310  * Test that of_fixed_clk_setup() registers a fixed rate clk with the proper
311  * accuracy.
312  */
clk_fixed_rate_of_accuracy_test(struct kunit * test)313 static void clk_fixed_rate_of_accuracy_test(struct kunit *test)
314 {
315 	struct clk_fixed_rate_of_test_context *ctx = test->priv;
316 	struct device *dev = ctx->dev;
317 	struct clk *clk;
318 
319 	clk = clk_get_kunit(test, dev, NULL);
320 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk);
321 
322 	KUNIT_EXPECT_EQ(test, TEST_FIXED_ACCURACY, clk_get_accuracy(clk));
323 }
324 
325 static struct kunit_case clk_fixed_rate_of_cases[] = {
326 	KUNIT_CASE(clk_fixed_rate_of_probe_test),
327 	KUNIT_CASE(clk_fixed_rate_of_accuracy_test),
328 	{}
329 };
330 
clk_fixed_rate_of_test_probe(struct platform_device * pdev)331 static int clk_fixed_rate_of_test_probe(struct platform_device *pdev)
332 {
333 	struct clk_fixed_rate_of_test_context *ctx;
334 
335 	ctx = pdev_to_clk_fixed_rate_of_test_context(pdev);
336 	ctx->dev = &pdev->dev;
337 	complete(&ctx->probed);
338 
339 	return 0;
340 }
341 
clk_fixed_rate_of_init(struct kunit * test)342 static int clk_fixed_rate_of_init(struct kunit *test)
343 {
344 	struct clk_fixed_rate_of_test_context *ctx;
345 	static const struct of_device_id match_table[] = {
346 		{ .compatible = "test,single-clk-consumer" },
347 		{ }
348 	};
349 
350 	KUNIT_ASSERT_EQ(test, 0, of_overlay_apply_kunit(test, kunit_clk_fixed_rate_test));
351 
352 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
353 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
354 	test->priv = ctx;
355 
356 	ctx->pdrv.probe = clk_fixed_rate_of_test_probe;
357 	ctx->pdrv.driver.of_match_table = match_table;
358 	ctx->pdrv.driver.name = __func__;
359 	ctx->pdrv.driver.owner = THIS_MODULE;
360 	init_completion(&ctx->probed);
361 
362 	KUNIT_ASSERT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
363 	KUNIT_ASSERT_NE(test, 0, wait_for_completion_timeout(&ctx->probed, HZ));
364 
365 	return 0;
366 }
367 
368 static struct kunit_suite clk_fixed_rate_of_suite = {
369 	.name = "clk_fixed_rate_of",
370 	.init = clk_fixed_rate_of_init,
371 	.test_cases = clk_fixed_rate_of_cases,
372 };
373 
374 kunit_test_suites(
375 	&clk_fixed_rate_suite,
376 	&clk_fixed_rate_of_suite,
377 	&clk_fixed_rate_parent_suite,
378 );
379 MODULE_LICENSE("GPL");
380 MODULE_DESCRIPTION("KUnit test for clk fixed rate basic type");
381