drivers/clk/at91/clk-system.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/at91/clk-system.c
Extension
.c
Size
2946 bytes
Lines
145
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 clk_system {
	struct clk_hw hw;
	struct regmap *regmap;
	struct at91_clk_pms pms;
	u8 id;
};

static inline int is_pck(int id)
{
	return (id >= 8) && (id <= 15);
}

static inline bool clk_system_ready(struct regmap *regmap, int id)
{
	unsigned int status;

	regmap_read(regmap, AT91_PMC_SR, &status);

	return !!(status & (1 << id));
}

static int clk_system_prepare(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);

	regmap_write(sys->regmap, AT91_PMC_SCER, 1 << sys->id);

	if (!is_pck(sys->id))
		return 0;

	while (!clk_system_ready(sys->regmap, sys->id))
		cpu_relax();

	return 0;
}

static void clk_system_unprepare(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);

	regmap_write(sys->regmap, AT91_PMC_SCDR, 1 << sys->id);
}

static int clk_system_is_prepared(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);
	unsigned int status;

	regmap_read(sys->regmap, AT91_PMC_SCSR, &status);

	if (!(status & (1 << sys->id)))
		return 0;

	if (!is_pck(sys->id))
		return 1;

	regmap_read(sys->regmap, AT91_PMC_SR, &status);

	return !!(status & (1 << sys->id));
}

static int clk_system_save_context(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);

	sys->pms.status = clk_system_is_prepared(hw);

	return 0;
}

static void clk_system_restore_context(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);

	if (sys->pms.status)
		clk_system_prepare(&sys->hw);
}

static const struct clk_ops system_ops = {
	.prepare = clk_system_prepare,
	.unprepare = clk_system_unprepare,
	.is_prepared = clk_system_is_prepared,
	.save_context = clk_system_save_context,
	.restore_context = clk_system_restore_context,
};

struct clk_hw * __init
at91_clk_register_system(struct regmap *regmap, const char *name,
			 const char *parent_name, struct clk_hw *parent_hw, u8 id,
			 unsigned long flags)

Annotation

Implementation Notes