1 // SPDX-License-Identifier: GPL-2.0
3 * Kunit test for clk gate basic type
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 u32 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, 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, ctx->fake_reg);
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));
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, 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, ctx->fake_reg);
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));
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 = 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, 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, ctx->fake_reg);
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));
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 = 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 = 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 = 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 = 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_LICENSE("GPL v2");