drivers/clk/clk-stm32h7.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-stm32h7.c
Extension
.c
Size
36997 bytes
Lines
1395
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 stm32_ready_gate {
	struct	clk_gate gate;
	u8	bit_rdy;
};

#define to_ready_gate_clk(_rgate) container_of(_rgate, struct stm32_ready_gate,\
		gate)

#define RGATE_TIMEOUT 10000

static int ready_gate_clk_enable(struct clk_hw *hw)
{
	struct clk_gate *gate = to_clk_gate(hw);
	struct stm32_ready_gate *rgate = to_ready_gate_clk(gate);
	int bit_status;
	unsigned int timeout = RGATE_TIMEOUT;

	if (clk_gate_ops.is_enabled(hw))
		return 0;

	clk_gate_ops.enable(hw);

	/* We can't use readl_poll_timeout() because we can blocked if
	 * someone enables this clock before clocksource changes.
	 * Only jiffies counter is available. Jiffies are incremented by
	 * interruptions and enable op does not allow to be interrupted.
	 */
	do {
		bit_status = !(readl(gate->reg) & BIT(rgate->bit_rdy));

		if (bit_status)
			udelay(100);

	} while (bit_status && --timeout);

	return bit_status;
}

static void ready_gate_clk_disable(struct clk_hw *hw)
{
	struct clk_gate *gate = to_clk_gate(hw);
	struct stm32_ready_gate *rgate = to_ready_gate_clk(gate);
	int bit_status;
	unsigned int timeout = RGATE_TIMEOUT;

	if (!clk_gate_ops.is_enabled(hw))
		return;

	clk_gate_ops.disable(hw);

	do {
		bit_status = !!(readl(gate->reg) & BIT(rgate->bit_rdy));

		if (bit_status)
			udelay(100);

	} while (bit_status && --timeout);
}

static const struct clk_ops ready_gate_clk_ops = {
	.enable		= ready_gate_clk_enable,
	.disable	= ready_gate_clk_disable,
	.is_enabled	= clk_gate_is_enabled,
};

static struct clk_hw *clk_register_ready_gate(struct device *dev,
		const char *name, const char *parent_name,
		void __iomem *reg, u8 bit_idx, u8 bit_rdy,
		unsigned long flags, spinlock_t *lock)
{
	struct stm32_ready_gate *rgate;
	struct clk_init_data init = { NULL };
	struct clk_hw *hw;
	int ret;

	rgate = kzalloc_obj(*rgate);
	if (!rgate)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &ready_gate_clk_ops;
	init.flags = flags;
	init.parent_names = &parent_name;
	init.num_parents = 1;

	rgate->bit_rdy = bit_rdy;
	rgate->gate.lock = lock;
	rgate->gate.reg = reg;
	rgate->gate.bit_idx = bit_idx;
	rgate->gate.hw.init = &init;

Annotation

Implementation Notes