diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index 90bd0e0b93d5..591897162056 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -3148,6 +3148,9 @@ static void clk_unregister_consumer_clk_prepare_fails(struct kunit *test)
 {
 	struct clk_unregister_consumer_clk_ctx *ctx = test->priv;
 
+	if (clk_hw_get_flags(&ctx->hw) & CLK_IS_CRITICAL)
+		kunit_skip(test, "Critical clks are already prepared");
+
 	clk_unregister_consumer_clk_unregister(test);
 
 	KUNIT_EXPECT_GT(test, 0, clk_prepare(ctx->clk));
@@ -3172,6 +3175,9 @@ static void clk_unregister_consumer_clk_enable_fails(struct kunit *test)
 {
 	struct clk_unregister_consumer_clk_ctx *ctx = test->priv;
 
+	if (clk_hw_get_flags(&ctx->hw) & CLK_IS_CRITICAL)
+		kunit_skip(test, "Critical clks are already enabled");
+
 	KUNIT_ASSERT_EQ(test, 0, clk_prepare(ctx->clk));
 	clk_unregister_consumer_clk_unregister(test);
 
@@ -3231,11 +3237,17 @@ static void clk_unregister_consumer_clk_set_rate_fails(struct kunit *test)
 static void clk_unregister_consumer_clk_get_rate_skips(struct kunit *test)
 {
 	struct clk_unregister_consumer_clk_ctx *ctx = test->priv;
+	const unsigned long flags = clk_hw_get_flags(&ctx->hw);
 
 	KUNIT_ASSERT_EQ(test, ctx->rate, clk_get_rate(ctx->clk));
 	clk_unregister_consumer_clk_unregister(test);
 
-	KUNIT_EXPECT_EQ(test, ctx->rate, clk_get_rate(ctx->clk));
+	if (flags & CLK_GET_RATE_NOCACHE) {
+		/* No cache clks start returning 0 and also skip */
+		KUNIT_EXPECT_EQ(test, 0, clk_get_rate(ctx->clk));
+	} else {
+		KUNIT_EXPECT_EQ(test, ctx->rate, clk_get_rate(ctx->clk));
+	}
 }
 
 /*
@@ -3245,11 +3257,17 @@ static void clk_unregister_consumer_clk_get_rate_skips(struct kunit *test)
 static void clk_unregister_consumer_clk_get_accuracy_skips(struct kunit *test)
 {
 	struct clk_unregister_consumer_clk_ctx *ctx = test->priv;
+	const unsigned long flags = clk_hw_get_flags(&ctx->hw);
 
 	KUNIT_ASSERT_EQ(test, ctx->accuracy, clk_get_accuracy(ctx->clk));
 	clk_unregister_consumer_clk_unregister(test);
 
-	KUNIT_EXPECT_EQ(test, ctx->accuracy, clk_get_accuracy(ctx->clk));
+	if (flags & CLK_GET_ACCURACY_NOCACHE) {
+		/* No cache clks start returning 0 and also skip */
+		KUNIT_EXPECT_EQ(test, 0, clk_get_accuracy(ctx->clk));
+	} else {
+		KUNIT_EXPECT_EQ(test, ctx->accuracy, clk_get_accuracy(ctx->clk));
+	}
 }
 
 /*
@@ -3334,7 +3352,8 @@ static void clk_unregister_consumer_clk_set_parent_fails(struct kunit *test)
 	/* Setting current parent is a no-op */
 	KUNIT_EXPECT_EQ(test, 0, clk_set_parent(ctx->clk, ctx->parents[0].clk));
 	/* Setting a new parent should fail */
-	KUNIT_EXPECT_GT(test, 0, clk_set_parent(ctx->clk, ctx->parents[1].clk));
+	if (ctx->parents[1].clk)
+		KUNIT_EXPECT_GT(test, 0, clk_set_parent(ctx->clk, ctx->parents[1].clk));
 	/* Parent is unchanged */
 	KUNIT_EXPECT_TRUE(test, clk_is_match(clk_get_parent(ctx->clk), ctx->parents[0].clk));
 }
@@ -3354,22 +3373,108 @@ static void clk_unregister_consumer_clk_get_parent_skips(struct kunit *test)
 	KUNIT_EXPECT_TRUE(test, clk_is_match(clk_get_parent(ctx->clk), ctx->parents[0].clk));
 }
 
+/**
+ * struct clk_register_params - Test parameters for different combinations of clk_init_data
+ * @clk_flags: Flags to set in struct clk_init_data::flags
+ * @num_parents: Number of parents to register (0, 1, or 2)
+ */
+struct clk_register_params {
+	unsigned long clk_flags;
+	unsigned int num_parents;
+};
+
+static void clk_register_params_to_desc(const char *test_name,
+					const struct clk_register_params *p,
+					char *desc)
+{
+	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s %d parents %#lx flags",
+		 test_name, p->num_parents, p->clk_flags);
+}
+
+/**
+ * clk_register_gen_params - Generate parameters for struct clk_init_data
+ * @test_name: Test name
+ * @_prev: Previous return value from this function
+ * @desc: Test description (to be filled in)
+ *
+ * Use this function in KUNIT_CASE_PARAM to generate struct clk_init_data
+ * parameters for a test that registers clks. It will return combinations of
+ * clk flags (exclusive of each other) and numbers of parents.
+ *
+ * Return: Test parameters in a struct clk_register_params.
+ */
+static const void *clk_register_gen_params(const char *test_name,
+					   const void *_prev, char *desc)
+{
+	const struct clk_register_params *prev = _prev;
+	struct clk_register_params *next;
+
+	next = krealloc(prev, sizeof(*next), GFP_KERNEL);
+	if (!next)
+		return NULL;
+	if (!prev)
+		memset(next, 0, sizeof(*next));
+
+	if (prev) {
+		if (next->clk_flags == 0)
+			next->clk_flags = 1;
+		else
+			next->clk_flags <<= 1;
+	}
+
+	if (next->clk_flags > CLK_DUTY_CYCLE_PARENT) {
+		next->clk_flags = 0;
+		next->num_parents++;
+		if (next->num_parents > 2)
+			return NULL;
+	}
+
+	clk_register_params_to_desc(test_name, next, desc);
+	return next;
+}
+
+#define CLK_REGISTER_GEN_PARAMS(name)					\
+	static const void *name##_gen_params(const void *prev,		\
+					    char *desc)			\
+	{								\
+		return clk_register_gen_params(#name, prev, desc);	\
+	}
+
+#define CLK_REGISTER_KUNIT_CASE_PARAM(name)				\
+	KUNIT_CASE_PARAM(name, name##_gen_params)
+
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_prepare_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_unprepare_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_enable_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_disable_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_round_rate_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_set_rate_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_get_rate_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_get_accuracy_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_set_phase_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_get_phase_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_set_duty_cycle_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_get_duty_cycle_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_set_parent_fails)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_get_parent_skips)
+CLK_REGISTER_GEN_PARAMS(clk_unregister_consumer_clk_put)
+
 static struct kunit_case clk_unregister_consumer_clk_test_cases[] = {
-	KUNIT_CASE(clk_unregister_consumer_clk_prepare_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_unprepare_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_enable_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_disable_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_round_rate_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_set_rate_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_get_rate_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_get_accuracy_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_set_phase_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_get_phase_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_set_duty_cycle_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_get_duty_cycle_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_set_parent_fails),
-	KUNIT_CASE(clk_unregister_consumer_clk_get_parent_skips),
-	KUNIT_CASE(clk_unregister_consumer_clk_put),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_prepare_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_unprepare_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_enable_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_disable_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_round_rate_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_set_rate_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_get_rate_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_get_accuracy_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_set_phase_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_get_phase_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_set_duty_cycle_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_get_duty_cycle_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_set_parent_fails),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_get_parent_skips),
+	CLK_REGISTER_KUNIT_CASE_PARAM(clk_unregister_consumer_clk_put),
 	{}
 };
 
@@ -3586,33 +3691,63 @@ static int clk_unregister_consumer_clk_init(struct kunit *test)
 	struct clk *clk;
 	struct clk_init_data init = { };
 	struct clk_unregister_consumer_clk_ctx *ctx;
-	struct clk_hw *parent0_hw, *parent1_hw;
+	struct clk_hw *parent0_hw = NULL;
+	struct clk_hw *parent1_hw = NULL;
+	const struct clk_register_params *test_param;
+	unsigned int num_parents;
+	unsigned long clk_flags;
+	struct clk_ops *clk_ops;
+
+	test_param = test->param_value;
+	if (test_param) {
+		num_parents = test_param->num_parents;
+		clk_flags = test_param->clk_flags;
+	} else {
+		num_parents = 0;
+		clk_flags = 0;
+	}
 
 	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 	test->priv = ctx;
 	ctx->test = test;
 
-	parent0_hw = &ctx->parents[0].ctx.hw;
-	parent0_hw->init = CLK_HW_INIT_NO_PARENT("parent-clk0",
-						&clk_dummy_rate_ops, 0);
-	KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, NULL, parent0_hw));
-	ctx->parents[0].clk = clk_hw_get_clk_kunit(test, parent0_hw, "p0");
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->parents[0].clk);
+	if (num_parents >= 1) {
+		parent0_hw = &ctx->parents[0].ctx.hw;
+		parent0_hw->init = CLK_HW_INIT_NO_PARENT("parent-clk0",
+							&clk_dummy_rate_ops, 0);
+		KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, NULL, parent0_hw));
+		ctx->parents[0].clk = clk_hw_get_clk_kunit(test, parent0_hw, "p0");
+		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->parents[0].clk);
+	}
 
-	parent1_hw = &ctx->parents[1].ctx.hw;
-	parent1_hw->init = CLK_HW_INIT_NO_PARENT("parent-clk1",
-						&clk_dummy_rate_ops, 0);
-	KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, NULL, parent1_hw));
-	ctx->parents[1].clk = clk_hw_get_clk_kunit(test, parent1_hw, "p1");
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->parents[1].clk);
+	if (num_parents >= 2) {
+		parent1_hw = &ctx->parents[1].ctx.hw;
+		parent1_hw->init = CLK_HW_INIT_NO_PARENT("parent-clk1",
+							&clk_dummy_rate_ops, 0);
+		KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, NULL, parent1_hw));
+		ctx->parents[1].clk = clk_hw_get_clk_kunit(test, parent1_hw, "p1");
+		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->parents[1].clk);
+	}
 
 	init.name = "unregister_consumer_clk_test_clk";
-	init.ops = &clk_unregister_consumer_clk_clk_ops;
-	init.parent_hws = (const struct clk_hw *[]){ parent0_hw, parent1_hw };
-	init.num_parents = ARRAY_SIZE(ctx->parents);
 	ctx->hw.init = &init;
 
+	clk_ops = kunit_kzalloc(test, sizeof(*clk_ops), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, clk_ops);
+	/* Copy clk_ops so we can modify them for different scenarios */
+	memcpy(clk_ops, &clk_unregister_consumer_clk_clk_ops, sizeof(*clk_ops));
+	init.ops = clk_ops;
+
+	init.flags = clk_flags;
+	init.num_parents = num_parents;
+	init.parent_hws = (const struct clk_hw *[]){ parent0_hw, parent1_hw };
+	if (!num_parents) {
+		clk_ops->get_parent = NULL;
+		clk_ops->set_parent = NULL;
+		clk_ops->set_rate_and_parent = NULL;
+	}
+
 	ctx->rate = 42;
 	ctx->accuracy = 34;
 	ctx->phase = 90;
