Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Kunit test for clk gate basic type
  4 */
  5#include <linux/clk.h>
  6#include <linux/clk-provider.h>
  7#include <linux/platform_device.h>
  8
  9#include <kunit/test.h>
 10
 11static void clk_gate_register_test_dev(struct kunit *test)
 12{
 13	struct clk_hw *ret;
 14	struct platform_device *pdev;
 15
 16	pdev = platform_device_register_simple("test_gate_device", -1, NULL, 0);
 17	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
 18
 19	ret = clk_hw_register_gate(&pdev->dev, "test_gate", NULL, 0, NULL,
 20				   0, 0, NULL);
 21	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
 22	KUNIT_EXPECT_STREQ(test, "test_gate", clk_hw_get_name(ret));
 23	KUNIT_EXPECT_EQ(test, 0UL, clk_hw_get_flags(ret));
 24
 25	clk_hw_unregister_gate(ret);
 26	platform_device_put(pdev);
 27}
 28
 29static void clk_gate_register_test_parent_names(struct kunit *test)
 30{
 31	struct clk_hw *parent;
 32	struct clk_hw *ret;
 33
 34	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
 35					    1000000);
 36	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
 37
 38	ret = clk_hw_register_gate(NULL, "test_gate", "test_parent", 0, NULL,
 39				   0, 0, NULL);
 40	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
 41	KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
 42
 43	clk_hw_unregister_gate(ret);
 44	clk_hw_unregister_fixed_rate(parent);
 45}
 46
 47static void clk_gate_register_test_parent_data(struct kunit *test)
 48{
 49	struct clk_hw *parent;
 50	struct clk_hw *ret;
 51	struct clk_parent_data pdata = { };
 52
 53	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
 54					    1000000);
 55	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
 56	pdata.hw = parent;
 57
 58	ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
 59					       NULL, 0, 0, NULL);
 60	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
 61	KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
 62
 63	clk_hw_unregister_gate(ret);
 64	clk_hw_unregister_fixed_rate(parent);
 65}
 66
 67static void clk_gate_register_test_parent_data_legacy(struct kunit *test)
 68{
 69	struct clk_hw *parent;
 70	struct clk_hw *ret;
 71	struct clk_parent_data pdata = { };
 72
 73	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
 74					    1000000);
 75	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
 76	pdata.name = "test_parent";
 77
 78	ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
 79					       NULL, 0, 0, NULL);
 80	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
 81	KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
 82
 83	clk_hw_unregister_gate(ret);
 84	clk_hw_unregister_fixed_rate(parent);
 85}
 86
 87static void clk_gate_register_test_parent_hw(struct kunit *test)
 88{
 89	struct clk_hw *parent;
 90	struct clk_hw *ret;
 91
 92	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
 93					    1000000);
 94	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
 95
 96	ret = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0, NULL,
 97					     0, 0, NULL);
 98	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
 99	KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
100
101	clk_hw_unregister_gate(ret);
102	clk_hw_unregister_fixed_rate(parent);
103}
104
105static void clk_gate_register_test_hiword_invalid(struct kunit *test)
106{
107	struct clk_hw *ret;
108
109	ret = clk_hw_register_gate(NULL, "test_gate", NULL, 0, NULL,
110				   20, CLK_GATE_HIWORD_MASK, NULL);
111
112	KUNIT_EXPECT_TRUE(test, IS_ERR(ret));
113}
114
115static struct kunit_case clk_gate_register_test_cases[] = {
116	KUNIT_CASE(clk_gate_register_test_dev),
117	KUNIT_CASE(clk_gate_register_test_parent_names),
118	KUNIT_CASE(clk_gate_register_test_parent_data),
119	KUNIT_CASE(clk_gate_register_test_parent_data_legacy),
120	KUNIT_CASE(clk_gate_register_test_parent_hw),
121	KUNIT_CASE(clk_gate_register_test_hiword_invalid),
122	{}
123};
124
125static struct kunit_suite clk_gate_register_test_suite = {
126	.name = "clk-gate-register-test",
127	.test_cases = clk_gate_register_test_cases,
128};
129
130struct clk_gate_test_context {
131	void __iomem *fake_mem;
132	struct clk_hw *hw;
133	struct clk_hw *parent;
134	u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
135};
136
137static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
138{
139	struct clk_gate_test_context *ctx;
140
141	test->priv = ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
142	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
143	ctx->fake_mem = (void __force __iomem *)&ctx->fake_reg;
144
145	return ctx;
146}
147
148static void clk_gate_test_parent_rate(struct kunit *test)
149{
150	struct clk_gate_test_context *ctx = test->priv;
151	struct clk_hw *parent = ctx->parent;
152	struct clk_hw *hw = ctx->hw;
153	unsigned long prate = clk_hw_get_rate(parent);
154	unsigned long rate = clk_hw_get_rate(hw);
155
156	KUNIT_EXPECT_EQ(test, prate, rate);
157}
158
159static void clk_gate_test_enable(struct kunit *test)
160{
161	struct clk_gate_test_context *ctx = test->priv;
162	struct clk_hw *parent = ctx->parent;
163	struct clk_hw *hw = ctx->hw;
164	struct clk *clk = hw->clk;
165	u32 enable_val = BIT(5);
166
167	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
168
169	KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
170	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
171	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
172	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
173	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
174}
175
176static void clk_gate_test_disable(struct kunit *test)
177{
178	struct clk_gate_test_context *ctx = test->priv;
179	struct clk_hw *parent = ctx->parent;
180	struct clk_hw *hw = ctx->hw;
181	struct clk *clk = hw->clk;
182	u32 enable_val = BIT(5);
183	u32 disable_val = 0;
184
185	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
186	KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
187
188	clk_disable_unprepare(clk);
189	KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
190	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
191	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
192	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
193	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
194}
195
196static struct kunit_case clk_gate_test_cases[] = {
197	KUNIT_CASE(clk_gate_test_parent_rate),
198	KUNIT_CASE(clk_gate_test_enable),
199	KUNIT_CASE(clk_gate_test_disable),
200	{}
201};
202
203static int clk_gate_test_init(struct kunit *test)
204{
205	struct clk_hw *parent;
206	struct clk_hw *hw;
207	struct clk_gate_test_context *ctx;
208
209	ctx = clk_gate_test_alloc_ctx(test);
210	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
211					    2000000);
212	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
213
214	hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
215					    ctx->fake_mem, 5, 0, NULL);
216	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
217
218	ctx->hw = hw;
219	ctx->parent = parent;
220
221	return 0;
222}
223
224static void clk_gate_test_exit(struct kunit *test)
225{
226	struct clk_gate_test_context *ctx = test->priv;
227
228	clk_hw_unregister_gate(ctx->hw);
229	clk_hw_unregister_fixed_rate(ctx->parent);
230}
231
232static struct kunit_suite clk_gate_test_suite = {
233	.name = "clk-gate-test",
234	.init = clk_gate_test_init,
235	.exit = clk_gate_test_exit,
236	.test_cases = clk_gate_test_cases,
237};
238
239static void clk_gate_test_invert_enable(struct kunit *test)
240{
241	struct clk_gate_test_context *ctx = test->priv;
242	struct clk_hw *parent = ctx->parent;
243	struct clk_hw *hw = ctx->hw;
244	struct clk *clk = hw->clk;
245	u32 enable_val = 0;
246
247	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
248
249	KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
250	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
251	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
252	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
253	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
254}
255
256static void clk_gate_test_invert_disable(struct kunit *test)
257{
258	struct clk_gate_test_context *ctx = test->priv;
259	struct clk_hw *parent = ctx->parent;
260	struct clk_hw *hw = ctx->hw;
261	struct clk *clk = hw->clk;
262	u32 enable_val = 0;
263	u32 disable_val = BIT(15);
264
265	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
266	KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
267
268	clk_disable_unprepare(clk);
269	KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
270	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
271	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
272	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
273	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
274}
275
276static struct kunit_case clk_gate_test_invert_cases[] = {
277	KUNIT_CASE(clk_gate_test_invert_enable),
278	KUNIT_CASE(clk_gate_test_invert_disable),
279	{}
280};
281
282static int clk_gate_test_invert_init(struct kunit *test)
283{
284	struct clk_hw *parent;
285	struct clk_hw *hw;
286	struct clk_gate_test_context *ctx;
287
288	ctx = clk_gate_test_alloc_ctx(test);
289	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
290					    2000000);
291	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
292
293	ctx->fake_reg = BIT(15); /* Default to off */
294	hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
295					    ctx->fake_mem, 15,
296					    CLK_GATE_SET_TO_DISABLE, NULL);
297	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
298
299	ctx->hw = hw;
300	ctx->parent = parent;
301
302	return 0;
303}
304
305static struct kunit_suite clk_gate_test_invert_suite = {
306	.name = "clk-gate-invert-test",
307	.init = clk_gate_test_invert_init,
308	.exit = clk_gate_test_exit,
309	.test_cases = clk_gate_test_invert_cases,
310};
311
312static void clk_gate_test_hiword_enable(struct kunit *test)
313{
314	struct clk_gate_test_context *ctx = test->priv;
315	struct clk_hw *parent = ctx->parent;
316	struct clk_hw *hw = ctx->hw;
317	struct clk *clk = hw->clk;
318	u32 enable_val = BIT(9) | BIT(9 + 16);
319
320	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
321
322	KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
323	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
324	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
325	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
326	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
327}
328
329static void clk_gate_test_hiword_disable(struct kunit *test)
330{
331	struct clk_gate_test_context *ctx = test->priv;
332	struct clk_hw *parent = ctx->parent;
333	struct clk_hw *hw = ctx->hw;
334	struct clk *clk = hw->clk;
335	u32 enable_val = BIT(9) | BIT(9 + 16);
336	u32 disable_val = BIT(9 + 16);
337
338	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
339	KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
340
341	clk_disable_unprepare(clk);
342	KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
343	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
344	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
345	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
346	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
347}
348
349static struct kunit_case clk_gate_test_hiword_cases[] = {
350	KUNIT_CASE(clk_gate_test_hiword_enable),
351	KUNIT_CASE(clk_gate_test_hiword_disable),
352	{}
353};
354
355static int clk_gate_test_hiword_init(struct kunit *test)
356{
357	struct clk_hw *parent;
358	struct clk_hw *hw;
359	struct clk_gate_test_context *ctx;
360
361	ctx = clk_gate_test_alloc_ctx(test);
362	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
363					    2000000);
364	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
365
366	hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
367					    ctx->fake_mem, 9,
368					    CLK_GATE_HIWORD_MASK, NULL);
369	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
370
371	ctx->hw = hw;
372	ctx->parent = parent;
373
374	return 0;
375}
376
377static struct kunit_suite clk_gate_test_hiword_suite = {
378	.name = "clk-gate-hiword-test",
379	.init = clk_gate_test_hiword_init,
380	.exit = clk_gate_test_exit,
381	.test_cases = clk_gate_test_hiword_cases,
382};
383
384static void clk_gate_test_is_enabled(struct kunit *test)
385{
386	struct clk_hw *hw;
387	struct clk_gate_test_context *ctx;
388
389	ctx = clk_gate_test_alloc_ctx(test);
390	ctx->fake_reg = BIT(7);
391	hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
392				  0, NULL);
393	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
394	KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
395
396	clk_hw_unregister_gate(hw);
397}
398
399static void clk_gate_test_is_disabled(struct kunit *test)
400{
401	struct clk_hw *hw;
402	struct clk_gate_test_context *ctx;
403
404	ctx = clk_gate_test_alloc_ctx(test);
405	ctx->fake_reg = BIT(4);
406	hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
407				  0, NULL);
408	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
409	KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
410
411	clk_hw_unregister_gate(hw);
412}
413
414static void clk_gate_test_is_enabled_inverted(struct kunit *test)
415{
416	struct clk_hw *hw;
417	struct clk_gate_test_context *ctx;
418
419	ctx = clk_gate_test_alloc_ctx(test);
420	ctx->fake_reg = BIT(31);
421	hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
422				  CLK_GATE_SET_TO_DISABLE, NULL);
423	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
424	KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
425
426	clk_hw_unregister_gate(hw);
427}
428
429static void clk_gate_test_is_disabled_inverted(struct kunit *test)
430{
431	struct clk_hw *hw;
432	struct clk_gate_test_context *ctx;
433
434	ctx = clk_gate_test_alloc_ctx(test);
435	ctx->fake_reg = BIT(29);
436	hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
437				  CLK_GATE_SET_TO_DISABLE, NULL);
438	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
439	KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
440
441	clk_hw_unregister_gate(hw);
442}
443
444static struct kunit_case clk_gate_test_enabled_cases[] = {
445	KUNIT_CASE(clk_gate_test_is_enabled),
446	KUNIT_CASE(clk_gate_test_is_disabled),
447	KUNIT_CASE(clk_gate_test_is_enabled_inverted),
448	KUNIT_CASE(clk_gate_test_is_disabled_inverted),
449	{}
450};
451
452static struct kunit_suite clk_gate_test_enabled_suite = {
453	.name = "clk-gate-is_enabled-test",
454	.test_cases = clk_gate_test_enabled_cases,
455};
456
457kunit_test_suites(
458	&clk_gate_register_test_suite,
459	&clk_gate_test_suite,
460	&clk_gate_test_invert_suite,
461	&clk_gate_test_hiword_suite,
462	&clk_gate_test_enabled_suite
463);
464MODULE_LICENSE("GPL v2");