381 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * KUnit test for clk fixed rate basic type4 */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 clk22 * @np: device_node of device registering clk23 * @name: name of clk24 * @parent_name: parent name of clk25 * @parent_hw: clk_hw pointer to parent of clk26 * @parent_data: parent_data describing parent of clk27 * @flags: clk framework flags28 * @fixed_rate: frequency of clk29 * @fixed_accuracy: accuracy of clk30 * @clk_fixed_flags: fixed rate specific clk flags31 */32struct 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 45static int46clk_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 69static 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 context79 * @params: Arguments to __clk_hw_register_fixed_rate()80 *81 * Return: Registered fixed rate clk_hw or ERR_PTR on failure82 */83static struct clk_hw *84clk_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 context102 * @hw: fixed rate clk to unregister upon test completion103 *104 * Automatically unregister @hw when @test is complete via105 * clk_hw_unregister_fixed_rate().106 *107 * Return: 0 on success or negative errno on failure108 */109static 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 with121 * clk_hw_register_fixed_rate() gets the proper frequency.122 */123static 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 via141 * clk_hw_register_fixed_rate_with_accuracy() gets the proper accuracy.142 */143static 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 */162static 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 168static 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 */176static 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 */207static 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 */237static 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 */266static 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 273static 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 278struct clk_fixed_rate_of_test_context {279 struct device *dev;280 struct platform_driver pdrv;281 struct completion probed;282};283 284static inline struct clk_fixed_rate_of_test_context *285pdev_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 proper294 * rate.295 */296static 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 proper311 * accuracy.312 */313static 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 325static 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 331static 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 342static 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 368static 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 374kunit_test_suites(375 &clk_fixed_rate_suite,376 &clk_fixed_rate_of_suite,377 &clk_fixed_rate_parent_suite,378);379MODULE_LICENSE("GPL");380MODULE_DESCRIPTION("KUnit test for clk fixed rate basic type");381