drivers/clk/imx/clk-gate2.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/imx/clk-gate2.c
Extension
.c
Size
4025 bytes
Lines
178
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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_gate2 {
	struct clk_hw hw;
	void __iomem	*reg;
	u8		bit_idx;
	u8		cgr_val;
	u8		cgr_mask;
	u8		flags;
	spinlock_t	*lock;
	unsigned int	*share_count;
};

#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)

static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	u32 reg;

	reg = readl(gate->reg);
	reg &= ~(gate->cgr_mask << gate->bit_idx);
	if (enable)
		reg |= (gate->cgr_val & gate->cgr_mask) << gate->bit_idx;
	writel(reg, gate->reg);
}

static int clk_gate2_enable(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;

	spin_lock_irqsave(gate->lock, flags);

	if (gate->share_count && (*gate->share_count)++ > 0)
		goto out;

	clk_gate2_do_shared_clks(hw, true);
out:
	spin_unlock_irqrestore(gate->lock, flags);

	return 0;
}

static void clk_gate2_disable(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;

	spin_lock_irqsave(gate->lock, flags);

	if (gate->share_count) {
		if (WARN_ON(*gate->share_count == 0))
			goto out;
		else if (--(*gate->share_count) > 0)
			goto out;
	}

	clk_gate2_do_shared_clks(hw, false);
out:
	spin_unlock_irqrestore(gate->lock, flags);
}

static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx,
					u8 cgr_val, u8 cgr_mask)
{
	u32 val = readl(reg);

	if (((val >> bit_idx) & cgr_mask) == cgr_val)
		return 1;

	return 0;
}

static int clk_gate2_is_enabled(struct clk_hw *hw)
{
	struct clk_gate2 *gate = to_clk_gate2(hw);
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(gate->lock, flags);

	ret = clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
					gate->cgr_val, gate->cgr_mask);

	spin_unlock_irqrestore(gate->lock, flags);

	return ret;
}

static void clk_gate2_disable_unused(struct clk_hw *hw)
{

Annotation

Implementation Notes