drivers/clk/mediatek/clk-mux.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/mediatek/clk-mux.c
Extension
.c
Size
10845 bytes
Lines
443
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 mtk_clk_mux {
	struct clk_hw hw;
	struct regmap *regmap;
	struct regmap *regmap_hwv;
	const struct mtk_mux *data;
	spinlock_t *lock;
	bool reparent;
};

static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
{
	return container_of(hw, struct mtk_clk_mux, hw);
}

static int mtk_clk_mux_fenc_enable_setclr(struct clk_hw *hw)
{
	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
	unsigned long flags;
	u32 val;
	int ret;

	if (mux->lock)
		spin_lock_irqsave(mux->lock, flags);
	else
		__acquire(mux->lock);

	regmap_write(mux->regmap, mux->data->clr_ofs,
		     BIT(mux->data->gate_shift));

	ret = regmap_read_poll_timeout_atomic(mux->regmap, mux->data->fenc_sta_mon_ofs,
					      val, val & BIT(mux->data->fenc_shift), 1,
					      MTK_WAIT_FENC_DONE_US);

	if (mux->lock)
		spin_unlock_irqrestore(mux->lock, flags);
	else
		__release(mux->lock);

	return ret;
}

static int mtk_clk_mux_enable_setclr(struct clk_hw *hw)
{
	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
	unsigned long flags = 0;

	if (mux->lock)
		spin_lock_irqsave(mux->lock, flags);
	else
		__acquire(mux->lock);

	regmap_write(mux->regmap, mux->data->clr_ofs,
		     BIT(mux->data->gate_shift));

	/*
	 * If the parent has been changed when the clock was disabled, it will
	 * not be effective yet. Set the update bit to ensure the mux gets
	 * updated.
	 */
	if (mux->reparent && mux->data->upd_shift >= 0) {
		regmap_write(mux->regmap, mux->data->upd_ofs,
			     BIT(mux->data->upd_shift));
		mux->reparent = false;
	}

	if (mux->lock)
		spin_unlock_irqrestore(mux->lock, flags);
	else
		__release(mux->lock);

	return 0;
}

static void mtk_clk_mux_disable_setclr(struct clk_hw *hw)
{
	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);

	regmap_write(mux->regmap, mux->data->set_ofs,
			BIT(mux->data->gate_shift));
}

static int mtk_clk_mux_fenc_is_enabled(struct clk_hw *hw)
{
	struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
	u32 val;

	regmap_read(mux->regmap, mux->data->fenc_sta_mon_ofs, &val);

	return !!(val & BIT(mux->data->fenc_shift));
}

Annotation

Implementation Notes