drivers/clk/clk-ep93xx.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-ep93xx.c
Extension
.c
Size
23588 bytes
Lines
854
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 ep93xx_clk {
	struct clk_hw hw;
	u16 idx;
	u16 reg;
	u32 mask;
	u8 bit_idx;
	u8 shift;
	u8 width;
	u8 num_div;
	const char *div;
};

struct ep93xx_clk_priv {
	spinlock_t lock;
	struct ep93xx_regmap_adev *aux_dev;
	struct device *dev;
	void __iomem *base;
	struct regmap *map;
	struct clk_hw *fixed[EP93XX_FIXED_CLK_COUNT];
	struct ep93xx_clk reg[];
};

static struct ep93xx_clk *ep93xx_clk_from(struct clk_hw *hw)
{
	return container_of(hw, struct ep93xx_clk, hw);
}

static struct ep93xx_clk_priv *ep93xx_priv_from(struct ep93xx_clk *clk)
{
	return container_of(clk, struct ep93xx_clk_priv, reg[clk->idx]);
}

static void ep93xx_clk_write(struct ep93xx_clk_priv *priv, unsigned int reg, unsigned int val)
{
	struct ep93xx_regmap_adev *aux = priv->aux_dev;

	aux->write(aux->map, aux->lock, reg, val);
}

static int ep93xx_clk_is_enabled(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	regmap_read(priv->map, clk->reg, &val);

	return !!(val & BIT(clk->bit_idx));
}

static int ep93xx_clk_enable(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	guard(spinlock_irqsave)(&priv->lock);

	regmap_read(priv->map, clk->reg, &val);
	val |= BIT(clk->bit_idx);

	ep93xx_clk_write(priv, clk->reg, val);

	return 0;
}

static void ep93xx_clk_disable(struct clk_hw *hw)
{
	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
	u32 val;

	guard(spinlock_irqsave)(&priv->lock);

	regmap_read(priv->map, clk->reg, &val);
	val &= ~BIT(clk->bit_idx);

	ep93xx_clk_write(priv, clk->reg, val);
}

static const struct clk_ops clk_ep93xx_gate_ops = {
	.enable = ep93xx_clk_enable,
	.disable = ep93xx_clk_disable,
	.is_enabled = ep93xx_clk_is_enabled,
};

static int ep93xx_clk_register_gate(struct ep93xx_clk *clk,
				    const char *name,
				    struct clk_parent_data *parent_data,
				    unsigned long flags,

Annotation

Implementation Notes