Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Kunit test for clk gate basic type
0004  */
0005 #include <linux/clk.h>
0006 #include <linux/clk-provider.h>
0007 #include <linux/platform_device.h>
0008 
0009 #include <kunit/test.h>
0010 
0011 static void clk_gate_register_test_dev(struct kunit *test)
0012 {
0013     struct clk_hw *ret;
0014     struct platform_device *pdev;
0015 
0016     pdev = platform_device_register_simple("test_gate_device", -1, NULL, 0);
0017     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
0018 
0019     ret = clk_hw_register_gate(&pdev->dev, "test_gate", NULL, 0, NULL,
0020                    0, 0, NULL);
0021     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
0022     KUNIT_EXPECT_STREQ(test, "test_gate", clk_hw_get_name(ret));
0023     KUNIT_EXPECT_EQ(test, 0UL, clk_hw_get_flags(ret));
0024 
0025     clk_hw_unregister_gate(ret);
0026     platform_device_put(pdev);
0027 }
0028 
0029 static void clk_gate_register_test_parent_names(struct kunit *test)
0030 {
0031     struct clk_hw *parent;
0032     struct clk_hw *ret;
0033 
0034     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0035                         1000000);
0036     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0037 
0038     ret = clk_hw_register_gate(NULL, "test_gate", "test_parent", 0, NULL,
0039                    0, 0, NULL);
0040     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
0041     KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
0042 
0043     clk_hw_unregister_gate(ret);
0044     clk_hw_unregister_fixed_rate(parent);
0045 }
0046 
0047 static void clk_gate_register_test_parent_data(struct kunit *test)
0048 {
0049     struct clk_hw *parent;
0050     struct clk_hw *ret;
0051     struct clk_parent_data pdata = { };
0052 
0053     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0054                         1000000);
0055     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0056     pdata.hw = parent;
0057 
0058     ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
0059                            NULL, 0, 0, NULL);
0060     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
0061     KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
0062 
0063     clk_hw_unregister_gate(ret);
0064     clk_hw_unregister_fixed_rate(parent);
0065 }
0066 
0067 static void clk_gate_register_test_parent_data_legacy(struct kunit *test)
0068 {
0069     struct clk_hw *parent;
0070     struct clk_hw *ret;
0071     struct clk_parent_data pdata = { };
0072 
0073     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0074                         1000000);
0075     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0076     pdata.name = "test_parent";
0077 
0078     ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
0079                            NULL, 0, 0, NULL);
0080     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
0081     KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
0082 
0083     clk_hw_unregister_gate(ret);
0084     clk_hw_unregister_fixed_rate(parent);
0085 }
0086 
0087 static void clk_gate_register_test_parent_hw(struct kunit *test)
0088 {
0089     struct clk_hw *parent;
0090     struct clk_hw *ret;
0091 
0092     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0093                         1000000);
0094     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0095 
0096     ret = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0, NULL,
0097                          0, 0, NULL);
0098     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
0099     KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
0100 
0101     clk_hw_unregister_gate(ret);
0102     clk_hw_unregister_fixed_rate(parent);
0103 }
0104 
0105 static void clk_gate_register_test_hiword_invalid(struct kunit *test)
0106 {
0107     struct clk_hw *ret;
0108 
0109     ret = clk_hw_register_gate(NULL, "test_gate", NULL, 0, NULL,
0110                    20, CLK_GATE_HIWORD_MASK, NULL);
0111 
0112     KUNIT_EXPECT_TRUE(test, IS_ERR(ret));
0113 }
0114 
0115 static struct kunit_case clk_gate_register_test_cases[] = {
0116     KUNIT_CASE(clk_gate_register_test_dev),
0117     KUNIT_CASE(clk_gate_register_test_parent_names),
0118     KUNIT_CASE(clk_gate_register_test_parent_data),
0119     KUNIT_CASE(clk_gate_register_test_parent_data_legacy),
0120     KUNIT_CASE(clk_gate_register_test_parent_hw),
0121     KUNIT_CASE(clk_gate_register_test_hiword_invalid),
0122     {}
0123 };
0124 
0125 static struct kunit_suite clk_gate_register_test_suite = {
0126     .name = "clk-gate-register-test",
0127     .test_cases = clk_gate_register_test_cases,
0128 };
0129 
0130 struct clk_gate_test_context {
0131     void __iomem *fake_mem;
0132     struct clk_hw *hw;
0133     struct clk_hw *parent;
0134     u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
0135 };
0136 
0137 static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
0138 {
0139     struct clk_gate_test_context *ctx;
0140 
0141     test->priv = ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
0142     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
0143     ctx->fake_mem = (void __force __iomem *)&ctx->fake_reg;
0144 
0145     return ctx;
0146 }
0147 
0148 static void clk_gate_test_parent_rate(struct kunit *test)
0149 {
0150     struct clk_gate_test_context *ctx = test->priv;
0151     struct clk_hw *parent = ctx->parent;
0152     struct clk_hw *hw = ctx->hw;
0153     unsigned long prate = clk_hw_get_rate(parent);
0154     unsigned long rate = clk_hw_get_rate(hw);
0155 
0156     KUNIT_EXPECT_EQ(test, prate, rate);
0157 }
0158 
0159 static void clk_gate_test_enable(struct kunit *test)
0160 {
0161     struct clk_gate_test_context *ctx = test->priv;
0162     struct clk_hw *parent = ctx->parent;
0163     struct clk_hw *hw = ctx->hw;
0164     struct clk *clk = hw->clk;
0165     u32 enable_val = BIT(5);
0166 
0167     KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
0168 
0169     KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
0170     KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
0171     KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
0172     KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
0173     KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
0174 }
0175 
0176 static void clk_gate_test_disable(struct kunit *test)
0177 {
0178     struct clk_gate_test_context *ctx = test->priv;
0179     struct clk_hw *parent = ctx->parent;
0180     struct clk_hw *hw = ctx->hw;
0181     struct clk *clk = hw->clk;
0182     u32 enable_val = BIT(5);
0183     u32 disable_val = 0;
0184 
0185     KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
0186     KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
0187 
0188     clk_disable_unprepare(clk);
0189     KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
0190     KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
0191     KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
0192     KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
0193     KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
0194 }
0195 
0196 static struct kunit_case clk_gate_test_cases[] = {
0197     KUNIT_CASE(clk_gate_test_parent_rate),
0198     KUNIT_CASE(clk_gate_test_enable),
0199     KUNIT_CASE(clk_gate_test_disable),
0200     {}
0201 };
0202 
0203 static int clk_gate_test_init(struct kunit *test)
0204 {
0205     struct clk_hw *parent;
0206     struct clk_hw *hw;
0207     struct clk_gate_test_context *ctx;
0208 
0209     ctx = clk_gate_test_alloc_ctx(test);
0210     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0211                         2000000);
0212     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0213 
0214     hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
0215                         ctx->fake_mem, 5, 0, NULL);
0216     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0217 
0218     ctx->hw = hw;
0219     ctx->parent = parent;
0220 
0221     return 0;
0222 }
0223 
0224 static void clk_gate_test_exit(struct kunit *test)
0225 {
0226     struct clk_gate_test_context *ctx = test->priv;
0227 
0228     clk_hw_unregister_gate(ctx->hw);
0229     clk_hw_unregister_fixed_rate(ctx->parent);
0230 }
0231 
0232 static struct kunit_suite clk_gate_test_suite = {
0233     .name = "clk-gate-test",
0234     .init = clk_gate_test_init,
0235     .exit = clk_gate_test_exit,
0236     .test_cases = clk_gate_test_cases,
0237 };
0238 
0239 static void clk_gate_test_invert_enable(struct kunit *test)
0240 {
0241     struct clk_gate_test_context *ctx = test->priv;
0242     struct clk_hw *parent = ctx->parent;
0243     struct clk_hw *hw = ctx->hw;
0244     struct clk *clk = hw->clk;
0245     u32 enable_val = 0;
0246 
0247     KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
0248 
0249     KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
0250     KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
0251     KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
0252     KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
0253     KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
0254 }
0255 
0256 static void clk_gate_test_invert_disable(struct kunit *test)
0257 {
0258     struct clk_gate_test_context *ctx = test->priv;
0259     struct clk_hw *parent = ctx->parent;
0260     struct clk_hw *hw = ctx->hw;
0261     struct clk *clk = hw->clk;
0262     u32 enable_val = 0;
0263     u32 disable_val = BIT(15);
0264 
0265     KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
0266     KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
0267 
0268     clk_disable_unprepare(clk);
0269     KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
0270     KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
0271     KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
0272     KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
0273     KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
0274 }
0275 
0276 static struct kunit_case clk_gate_test_invert_cases[] = {
0277     KUNIT_CASE(clk_gate_test_invert_enable),
0278     KUNIT_CASE(clk_gate_test_invert_disable),
0279     {}
0280 };
0281 
0282 static int clk_gate_test_invert_init(struct kunit *test)
0283 {
0284     struct clk_hw *parent;
0285     struct clk_hw *hw;
0286     struct clk_gate_test_context *ctx;
0287 
0288     ctx = clk_gate_test_alloc_ctx(test);
0289     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0290                         2000000);
0291     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0292 
0293     ctx->fake_reg = BIT(15); /* Default to off */
0294     hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
0295                         ctx->fake_mem, 15,
0296                         CLK_GATE_SET_TO_DISABLE, NULL);
0297     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0298 
0299     ctx->hw = hw;
0300     ctx->parent = parent;
0301 
0302     return 0;
0303 }
0304 
0305 static struct kunit_suite clk_gate_test_invert_suite = {
0306     .name = "clk-gate-invert-test",
0307     .init = clk_gate_test_invert_init,
0308     .exit = clk_gate_test_exit,
0309     .test_cases = clk_gate_test_invert_cases,
0310 };
0311 
0312 static void clk_gate_test_hiword_enable(struct kunit *test)
0313 {
0314     struct clk_gate_test_context *ctx = test->priv;
0315     struct clk_hw *parent = ctx->parent;
0316     struct clk_hw *hw = ctx->hw;
0317     struct clk *clk = hw->clk;
0318     u32 enable_val = BIT(9) | BIT(9 + 16);
0319 
0320     KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
0321 
0322     KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
0323     KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
0324     KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
0325     KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
0326     KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
0327 }
0328 
0329 static void clk_gate_test_hiword_disable(struct kunit *test)
0330 {
0331     struct clk_gate_test_context *ctx = test->priv;
0332     struct clk_hw *parent = ctx->parent;
0333     struct clk_hw *hw = ctx->hw;
0334     struct clk *clk = hw->clk;
0335     u32 enable_val = BIT(9) | BIT(9 + 16);
0336     u32 disable_val = BIT(9 + 16);
0337 
0338     KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
0339     KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
0340 
0341     clk_disable_unprepare(clk);
0342     KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
0343     KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
0344     KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
0345     KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
0346     KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
0347 }
0348 
0349 static struct kunit_case clk_gate_test_hiword_cases[] = {
0350     KUNIT_CASE(clk_gate_test_hiword_enable),
0351     KUNIT_CASE(clk_gate_test_hiword_disable),
0352     {}
0353 };
0354 
0355 static int clk_gate_test_hiword_init(struct kunit *test)
0356 {
0357     struct clk_hw *parent;
0358     struct clk_hw *hw;
0359     struct clk_gate_test_context *ctx;
0360 
0361     ctx = clk_gate_test_alloc_ctx(test);
0362     parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
0363                         2000000);
0364     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
0365 
0366     hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
0367                         ctx->fake_mem, 9,
0368                         CLK_GATE_HIWORD_MASK, NULL);
0369     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0370 
0371     ctx->hw = hw;
0372     ctx->parent = parent;
0373 
0374     return 0;
0375 }
0376 
0377 static struct kunit_suite clk_gate_test_hiword_suite = {
0378     .name = "clk-gate-hiword-test",
0379     .init = clk_gate_test_hiword_init,
0380     .exit = clk_gate_test_exit,
0381     .test_cases = clk_gate_test_hiword_cases,
0382 };
0383 
0384 static void clk_gate_test_is_enabled(struct kunit *test)
0385 {
0386     struct clk_hw *hw;
0387     struct clk_gate_test_context *ctx;
0388 
0389     ctx = clk_gate_test_alloc_ctx(test);
0390     ctx->fake_reg = BIT(7);
0391     hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
0392                   0, NULL);
0393     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0394     KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
0395 
0396     clk_hw_unregister_gate(hw);
0397 }
0398 
0399 static void clk_gate_test_is_disabled(struct kunit *test)
0400 {
0401     struct clk_hw *hw;
0402     struct clk_gate_test_context *ctx;
0403 
0404     ctx = clk_gate_test_alloc_ctx(test);
0405     ctx->fake_reg = BIT(4);
0406     hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
0407                   0, NULL);
0408     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0409     KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
0410 
0411     clk_hw_unregister_gate(hw);
0412 }
0413 
0414 static void clk_gate_test_is_enabled_inverted(struct kunit *test)
0415 {
0416     struct clk_hw *hw;
0417     struct clk_gate_test_context *ctx;
0418 
0419     ctx = clk_gate_test_alloc_ctx(test);
0420     ctx->fake_reg = BIT(31);
0421     hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
0422                   CLK_GATE_SET_TO_DISABLE, NULL);
0423     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0424     KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
0425 
0426     clk_hw_unregister_gate(hw);
0427 }
0428 
0429 static void clk_gate_test_is_disabled_inverted(struct kunit *test)
0430 {
0431     struct clk_hw *hw;
0432     struct clk_gate_test_context *ctx;
0433 
0434     ctx = clk_gate_test_alloc_ctx(test);
0435     ctx->fake_reg = BIT(29);
0436     hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
0437                   CLK_GATE_SET_TO_DISABLE, NULL);
0438     KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
0439     KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
0440 
0441     clk_hw_unregister_gate(hw);
0442 }
0443 
0444 static struct kunit_case clk_gate_test_enabled_cases[] = {
0445     KUNIT_CASE(clk_gate_test_is_enabled),
0446     KUNIT_CASE(clk_gate_test_is_disabled),
0447     KUNIT_CASE(clk_gate_test_is_enabled_inverted),
0448     KUNIT_CASE(clk_gate_test_is_disabled_inverted),
0449     {}
0450 };
0451 
0452 static struct kunit_suite clk_gate_test_enabled_suite = {
0453     .name = "clk-gate-is_enabled-test",
0454     .test_cases = clk_gate_test_enabled_cases,
0455 };
0456 
0457 kunit_test_suites(
0458     &clk_gate_register_test_suite,
0459     &clk_gate_test_suite,
0460     &clk_gate_test_invert_suite,
0461     &clk_gate_test_hiword_suite,
0462     &clk_gate_test_enabled_suite
0463 );
0464 MODULE_LICENSE("GPL v2");