drivers/clk/clk-gate_test.c

Source file repositories/reference/linux-study-clean/drivers/clk/clk-gate_test.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-gate_test.c
Extension
.c
Size
13390 bytes
Lines
466
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct clk_gate_test_context {
	void __iomem *fake_mem;
	struct clk_hw *hw;
	struct clk_hw *parent;
	__le32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
};

static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
{
	struct clk_gate_test_context *ctx;

	test->priv = ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
	ctx->fake_mem = (void __force __iomem *)&ctx->fake_reg;

	return ctx;
}

static void clk_gate_test_parent_rate(struct kunit *test)
{
	struct clk_gate_test_context *ctx = test->priv;
	struct clk_hw *parent = ctx->parent;
	struct clk_hw *hw = ctx->hw;
	unsigned long prate = clk_hw_get_rate(parent);
	unsigned long rate = clk_hw_get_rate(hw);

	KUNIT_EXPECT_EQ(test, prate, rate);
}

static void clk_gate_test_enable(struct kunit *test)
{
	struct clk_gate_test_context *ctx = test->priv;
	struct clk_hw *parent = ctx->parent;
	struct clk_hw *hw = ctx->hw;
	struct clk *clk = hw->clk;
	u32 enable_val = BIT(5);

	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);

	KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
	KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
	KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
}

static void clk_gate_test_disable(struct kunit *test)
{
	struct clk_gate_test_context *ctx = test->priv;
	struct clk_hw *parent = ctx->parent;
	struct clk_hw *hw = ctx->hw;
	struct clk *clk = hw->clk;
	u32 enable_val = BIT(5);
	u32 disable_val = 0;

	KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
	KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));

	clk_disable_unprepare(clk);
	KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
	KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
	KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
}

static struct kunit_case clk_gate_test_cases[] = {
	KUNIT_CASE(clk_gate_test_parent_rate),
	KUNIT_CASE(clk_gate_test_enable),
	KUNIT_CASE(clk_gate_test_disable),
	{}
};

static int clk_gate_test_init(struct kunit *test)
{
	struct clk_hw *parent;
	struct clk_hw *hw;
	struct clk_gate_test_context *ctx;

	ctx = clk_gate_test_alloc_ctx(test);
	parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
					    2000000);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);

	hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
					    ctx->fake_mem, 5, 0, NULL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);

	ctx->hw = hw;
	ctx->parent = parent;

Annotation

Implementation Notes