drivers/clk/imx/clk-gate-93.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/imx/clk-gate-93.c
Extension
.c
Size
4485 bytes
Lines
200
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 imx93_clk_gate {
	struct clk_hw hw;
	void __iomem	*reg;
	u32		bit_idx;
	u32		val;
	u32		mask;
	spinlock_t	*lock;
	unsigned int	*share_count;
};

#define to_imx93_clk_gate(_hw) container_of(_hw, struct imx93_clk_gate, hw)

static void imx93_clk_gate_do_hardware(struct clk_hw *hw, bool enable)
{
	struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
	u32 val;

	val = readl(gate->reg + AUTHEN_OFFSET);
	if (val & CPULPM_EN) {
		val = enable ? LPM_SETTING_ON : LPM_SETTING_OFF;
		writel(val, gate->reg + LPM_CUR_OFFSET);
	} else {
		val = readl(gate->reg + DIRECT_OFFSET);
		val &= ~(gate->mask << gate->bit_idx);
		if (enable)
			val |= (gate->val & gate->mask) << gate->bit_idx;
		writel(val, gate->reg + DIRECT_OFFSET);
	}
}

static int imx93_clk_gate_enable(struct clk_hw *hw)
{
	struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
	unsigned long flags;

	spin_lock_irqsave(gate->lock, flags);

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

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

	return 0;
}

static void imx93_clk_gate_disable(struct clk_hw *hw)
{
	struct imx93_clk_gate *gate = to_imx93_clk_gate(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;
	}

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

static int imx93_clk_gate_reg_is_enabled(struct imx93_clk_gate *gate)
{
	u32 val = readl(gate->reg + AUTHEN_OFFSET);

	if (val & CPULPM_EN) {
		val = readl(gate->reg + LPM_CUR_OFFSET);
		if (val == LPM_SETTING_ON)
			return 1;
	} else {
		val = readl(gate->reg);
		if (((val >> gate->bit_idx) & gate->mask) == gate->val)
			return 1;
	}

	return 0;
}

static int imx93_clk_gate_is_enabled(struct clk_hw *hw)
{
	struct imx93_clk_gate *gate = to_imx93_clk_gate(hw);
	unsigned long flags;
	int ret;

	spin_lock_irqsave(gate->lock, flags);

Annotation

Implementation Notes