drivers/clk/sophgo/clk-sg2044.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/sophgo/clk-sg2044.c
Extension
.c
Size
50336 bytes
Lines
1813
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 sg2044_div_internal {
	u32	offset;
	u32	initval;
	u8	shift;
	u8	width;
	u16	flags;
};

struct sg2044_mux_internal {
	const u32	*table;
	u32		offset;
	u16		shift;
	u16		flags;
};

struct sg2044_gate_internal {
	u32	offset;
	u16	shift;
	u16	flags;
};

struct sg2044_clk_common {
	struct clk_hw	hw;
	void __iomem	*base;
	spinlock_t	*lock;
	unsigned int	id;
};

struct sg2044_div {
	struct sg2044_clk_common	common;
	struct sg2044_div_internal	div;
};

struct sg2044_mux {
	struct sg2044_clk_common	common;
	struct sg2044_mux_internal	mux;
	struct notifier_block		nb;
	u8				saved_parent;
};

struct sg2044_gate {
	struct sg2044_clk_common	common;
	struct sg2044_gate_internal	gate;
};

struct sg2044_clk_ctrl {
	spinlock_t			lock;
	struct clk_hw_onecell_data	data;
};

struct sg2044_clk_desc_data {
	struct sg2044_clk_common	* const *pll;
	struct sg2044_clk_common	* const *div;
	struct sg2044_clk_common	* const *mux;
	struct sg2044_clk_common	* const *gate;
	u16				num_pll;
	u16				num_div;
	u16				num_mux;
	u16				num_gate;
};

#define hw_to_sg2044_clk_common(_hw)					\
	container_of((_hw), struct sg2044_clk_common, hw)

static inline struct sg2044_div *hw_to_sg2044_div(struct clk_hw *hw)
{
	return container_of(hw_to_sg2044_clk_common(hw),
			    struct sg2044_div, common);
}

static u32 sg2044_div_get_reg_div(u32 reg, struct sg2044_div_internal *div)
{
	if ((reg & DIV_FACTOR_REG_SOURCE))
		return (reg >> div->shift) & clk_div_mask(div->width);

	return div->initval == 0 ? 1 : div->initval;
}

static unsigned long _sg2044_div_recalc_rate(struct sg2044_clk_common *common,
					     struct sg2044_div_internal *div,
					     unsigned long parent_rate)
{
	u32 reg = readl(common->base + div->offset);
	u32 val = sg2044_div_get_reg_div(reg, div);

	return divider_recalc_rate(&common->hw, parent_rate, val, NULL,
				   div->flags, div->width);
}

static unsigned long sg2044_div_recalc_rate(struct clk_hw *hw,

Annotation

Implementation Notes