Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: Add KUnit tests for clk fixed rate basic type

Test that the fixed rate basic type clk works as intended.

Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@google.com>
Cc: Rae Moar <rmoar@google.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://lore.kernel.org/r/20240718210513.3801024-8-sboyd@kernel.org

+420
+2
drivers/clk/.kunitconfig
··· 1 1 CONFIG_KUNIT=y 2 + CONFIG_OF=y 2 3 CONFIG_COMMON_CLK=y 3 4 CONFIG_CLK_KUNIT_TEST=y 5 + CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y 4 6 CONFIG_CLK_GATE_KUNIT_TEST=y 5 7 CONFIG_CLK_FD_KUNIT_TEST=y 6 8 CONFIG_UML_PCI_OVER_VIRTIO=n
+9
drivers/clk/Kconfig
··· 512 512 help 513 513 Kunit tests for the common clock framework. 514 514 515 + config CLK_FIXED_RATE_KUNIT_TEST 516 + tristate "Basic fixed rate clk type KUnit test" if !KUNIT_ALL_TESTS 517 + depends on KUNIT 518 + default KUNIT_ALL_TESTS 519 + select OF_OVERLAY if OF 520 + select DTC 521 + help 522 + KUnit tests for the basic fixed rate clk type. 523 + 515 524 config CLK_GATE_KUNIT_TEST 516 525 tristate "Basic gate type Kunit test" if !KUNIT_ALL_TESTS 517 526 depends on KUNIT
+2
drivers/clk/Makefile
··· 6 6 obj-$(CONFIG_COMMON_CLK) += clk-divider.o 7 7 obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o 8 8 obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o 9 + obj-$(CONFIG_CLK_FIXED_RATE_KUNIT_TEST) += clk-fixed-rate-test.o 10 + clk-fixed-rate-test-y := clk-fixed-rate_test.o kunit_clk_fixed_rate_test.dtbo.o 9 11 obj-$(CONFIG_COMMON_CLK) += clk-gate.o 10 12 obj-$(CONFIG_CLK_GATE_KUNIT_TEST) += clk-gate_test.o 11 13 obj-$(CONFIG_COMMON_CLK) += clk-multiplier.o
+380
drivers/clk/clk-fixed-rate_test.c
··· 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 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 + 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 * 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 + */ 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 + */ 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 + */ 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 + */ 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 + */ 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 + */ 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 * 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 + */ 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 + */ 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 + 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 + 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");
+8
drivers/clk/clk-fixed-rate_test.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _CLK_FIXED_RATE_TEST_H 3 + #define _CLK_FIXED_RATE_TEST_H 4 + 5 + #define TEST_FIXED_FREQUENCY 50000000 6 + #define TEST_FIXED_ACCURACY 300 7 + 8 + #endif
+19
drivers/clk/kunit_clk_fixed_rate_test.dtso
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /dts-v1/; 3 + /plugin/; 4 + 5 + #include "clk-fixed-rate_test.h" 6 + 7 + &{/} { 8 + fixed_50MHz: kunit-clock { 9 + compatible = "fixed-clock"; 10 + #clock-cells = <0>; 11 + clock-frequency = <TEST_FIXED_FREQUENCY>; 12 + clock-accuracy = <TEST_FIXED_ACCURACY>; 13 + }; 14 + 15 + kunit-clock-consumer { 16 + compatible = "test,single-clk-consumer"; 17 + clocks = <&fixed_50MHz>; 18 + }; 19 + };