1 // SPDX-License-Identifier: GPL-2.0
3 * Kunit tests for clk gate
6 #include <linux/clk-provider.h>
7 #include <linux/platform_device.h>
9 #include <kunit/test.h>
11 static void clk_gate_register_test_dev(struct kunit
*test
)
14 struct platform_device
*pdev
;
16 pdev
= platform_device_register_simple("test_gate_device", -1, NULL
, 0);
17 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, pdev
);
19 ret
= clk_hw_register_gate(&pdev
->dev
, "test_gate", NULL
, 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
));
25 clk_hw_unregister_gate(ret
);
26 platform_device_put(pdev
);
29 static void clk_gate_register_test_parent_names(struct kunit
*test
)
31 struct clk_hw
*parent
;
34 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
36 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
38 ret
= clk_hw_register_gate(NULL
, "test_gate", "test_parent", 0, NULL
,
40 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, ret
);
41 KUNIT_EXPECT_PTR_EQ(test
, parent
, clk_hw_get_parent(ret
));
43 clk_hw_unregister_gate(ret
);
44 clk_hw_unregister_fixed_rate(parent
);
47 static void clk_gate_register_test_parent_data(struct kunit
*test
)
49 struct clk_hw
*parent
;
51 struct clk_parent_data pdata
= { };
53 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
55 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
58 ret
= clk_hw_register_gate_parent_data(NULL
, "test_gate", &pdata
, 0,
60 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, ret
);
61 KUNIT_EXPECT_PTR_EQ(test
, parent
, clk_hw_get_parent(ret
));
63 clk_hw_unregister_gate(ret
);
64 clk_hw_unregister_fixed_rate(parent
);
67 static void clk_gate_register_test_parent_data_legacy(struct kunit
*test
)
69 struct clk_hw
*parent
;
71 struct clk_parent_data pdata
= { };
73 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
75 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
76 pdata
.name
= "test_parent";
78 ret
= clk_hw_register_gate_parent_data(NULL
, "test_gate", &pdata
, 0,
80 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, ret
);
81 KUNIT_EXPECT_PTR_EQ(test
, parent
, clk_hw_get_parent(ret
));
83 clk_hw_unregister_gate(ret
);
84 clk_hw_unregister_fixed_rate(parent
);
87 static void clk_gate_register_test_parent_hw(struct kunit
*test
)
89 struct clk_hw
*parent
;
92 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
94 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
96 ret
= clk_hw_register_gate_parent_hw(NULL
, "test_gate", parent
, 0, NULL
,
98 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, ret
);
99 KUNIT_EXPECT_PTR_EQ(test
, parent
, clk_hw_get_parent(ret
));
101 clk_hw_unregister_gate(ret
);
102 clk_hw_unregister_fixed_rate(parent
);
105 static void clk_gate_register_test_hiword_invalid(struct kunit
*test
)
109 ret
= clk_hw_register_gate(NULL
, "test_gate", NULL
, 0, NULL
,
110 20, CLK_GATE_HIWORD_MASK
, NULL
);
112 KUNIT_EXPECT_TRUE(test
, IS_ERR(ret
));
115 static 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
),
125 static struct kunit_suite clk_gate_register_test_suite
= {
126 .name
= "clk-gate-register-test",
127 .test_cases
= clk_gate_register_test_cases
,
130 struct clk_gate_test_context
{
131 void __iomem
*fake_mem
;
133 struct clk_hw
*parent
;
134 __le32 fake_reg
; /* Keep at end, KASAN can detect out of bounds */
137 static struct clk_gate_test_context
*clk_gate_test_alloc_ctx(struct kunit
*test
)
139 struct clk_gate_test_context
*ctx
;
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
;
148 static void clk_gate_test_parent_rate(struct kunit
*test
)
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
);
156 KUNIT_EXPECT_EQ(test
, prate
, rate
);
159 static void clk_gate_test_enable(struct kunit
*test
)
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);
167 KUNIT_ASSERT_EQ(test
, clk_prepare_enable(clk
), 0);
169 KUNIT_EXPECT_EQ(test
, enable_val
, le32_to_cpu(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
));
176 static void clk_gate_test_disable(struct kunit
*test
)
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);
185 KUNIT_ASSERT_EQ(test
, clk_prepare_enable(clk
), 0);
186 KUNIT_ASSERT_EQ(test
, enable_val
, le32_to_cpu(ctx
->fake_reg
));
188 clk_disable_unprepare(clk
);
189 KUNIT_EXPECT_EQ(test
, disable_val
, le32_to_cpu(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
));
196 static 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
),
203 static int clk_gate_test_init(struct kunit
*test
)
205 struct clk_hw
*parent
;
207 struct clk_gate_test_context
*ctx
;
209 ctx
= clk_gate_test_alloc_ctx(test
);
210 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
212 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
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
);
219 ctx
->parent
= parent
;
224 static void clk_gate_test_exit(struct kunit
*test
)
226 struct clk_gate_test_context
*ctx
= test
->priv
;
228 clk_hw_unregister_gate(ctx
->hw
);
229 clk_hw_unregister_fixed_rate(ctx
->parent
);
232 static 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
,
239 static void clk_gate_test_invert_enable(struct kunit
*test
)
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
;
247 KUNIT_ASSERT_EQ(test
, clk_prepare_enable(clk
), 0);
249 KUNIT_EXPECT_EQ(test
, enable_val
, le32_to_cpu(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
));
256 static void clk_gate_test_invert_disable(struct kunit
*test
)
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
;
263 u32 disable_val
= BIT(15);
265 KUNIT_ASSERT_EQ(test
, clk_prepare_enable(clk
), 0);
266 KUNIT_ASSERT_EQ(test
, enable_val
, le32_to_cpu(ctx
->fake_reg
));
268 clk_disable_unprepare(clk
);
269 KUNIT_EXPECT_EQ(test
, disable_val
, le32_to_cpu(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
));
276 static struct kunit_case clk_gate_test_invert_cases
[] = {
277 KUNIT_CASE(clk_gate_test_invert_enable
),
278 KUNIT_CASE(clk_gate_test_invert_disable
),
282 static int clk_gate_test_invert_init(struct kunit
*test
)
284 struct clk_hw
*parent
;
286 struct clk_gate_test_context
*ctx
;
288 ctx
= clk_gate_test_alloc_ctx(test
);
289 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
291 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
293 ctx
->fake_reg
= cpu_to_le32(BIT(15)); /* Default to off */
294 hw
= clk_hw_register_gate_parent_hw(NULL
, "test_gate", parent
, 0,
296 CLK_GATE_SET_TO_DISABLE
, NULL
);
297 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, hw
);
300 ctx
->parent
= parent
;
305 static 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
,
312 static void clk_gate_test_hiword_enable(struct kunit
*test
)
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);
320 KUNIT_ASSERT_EQ(test
, clk_prepare_enable(clk
), 0);
322 KUNIT_EXPECT_EQ(test
, enable_val
, le32_to_cpu(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
));
329 static void clk_gate_test_hiword_disable(struct kunit
*test
)
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);
338 KUNIT_ASSERT_EQ(test
, clk_prepare_enable(clk
), 0);
339 KUNIT_ASSERT_EQ(test
, enable_val
, le32_to_cpu(ctx
->fake_reg
));
341 clk_disable_unprepare(clk
);
342 KUNIT_EXPECT_EQ(test
, disable_val
, le32_to_cpu(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
));
349 static struct kunit_case clk_gate_test_hiword_cases
[] = {
350 KUNIT_CASE(clk_gate_test_hiword_enable
),
351 KUNIT_CASE(clk_gate_test_hiword_disable
),
355 static int clk_gate_test_hiword_init(struct kunit
*test
)
357 struct clk_hw
*parent
;
359 struct clk_gate_test_context
*ctx
;
361 ctx
= clk_gate_test_alloc_ctx(test
);
362 parent
= clk_hw_register_fixed_rate(NULL
, "test_parent", NULL
, 0,
364 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, parent
);
366 hw
= clk_hw_register_gate_parent_hw(NULL
, "test_gate", parent
, 0,
368 CLK_GATE_HIWORD_MASK
, NULL
);
369 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, hw
);
372 ctx
->parent
= parent
;
377 static 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
,
384 static void clk_gate_test_is_enabled(struct kunit
*test
)
387 struct clk_gate_test_context
*ctx
;
389 ctx
= clk_gate_test_alloc_ctx(test
);
390 ctx
->fake_reg
= cpu_to_le32(BIT(7));
391 hw
= clk_hw_register_gate(NULL
, "test_gate", NULL
, 0, ctx
->fake_mem
, 7,
393 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, hw
);
394 KUNIT_ASSERT_TRUE(test
, clk_hw_is_enabled(hw
));
396 clk_hw_unregister_gate(hw
);
399 static void clk_gate_test_is_disabled(struct kunit
*test
)
402 struct clk_gate_test_context
*ctx
;
404 ctx
= clk_gate_test_alloc_ctx(test
);
405 ctx
->fake_reg
= cpu_to_le32(BIT(4));
406 hw
= clk_hw_register_gate(NULL
, "test_gate", NULL
, 0, ctx
->fake_mem
, 7,
408 KUNIT_ASSERT_NOT_ERR_OR_NULL(test
, hw
);
409 KUNIT_ASSERT_FALSE(test
, clk_hw_is_enabled(hw
));
411 clk_hw_unregister_gate(hw
);
414 static void clk_gate_test_is_enabled_inverted(struct kunit
*test
)
417 struct clk_gate_test_context
*ctx
;
419 ctx
= clk_gate_test_alloc_ctx(test
);
420 ctx
->fake_reg
= cpu_to_le32(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
));
426 clk_hw_unregister_gate(hw
);
429 static void clk_gate_test_is_disabled_inverted(struct kunit
*test
)
432 struct clk_gate_test_context
*ctx
;
434 ctx
= clk_gate_test_alloc_ctx(test
);
435 ctx
->fake_reg
= cpu_to_le32(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
));
441 clk_hw_unregister_gate(hw
);
444 static 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
),
452 static struct kunit_suite clk_gate_test_enabled_suite
= {
453 .name
= "clk-gate-is_enabled-test",
454 .test_cases
= clk_gate_test_enabled_cases
,
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
464 MODULE_DESCRIPTION("Kunit tests for clk gate");
465 MODULE_LICENSE("GPL v2");