drivers/clk/at91/sckc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/at91/sckc.c
Extension
.c
Size
15337 bytes
Lines
658
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_slow_bits {
	u32 cr_rcen;
	u32 cr_osc32en;
	u32 cr_osc32byp;
	u32 cr_oscsel;
};

struct clk_slow_osc {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	unsigned long startup_usec;
};

#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)

struct clk_sama5d4_slow_osc {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	unsigned long startup_usec;
	bool prepared;
};

#define to_clk_sama5d4_slow_osc(hw) container_of(hw, struct clk_sama5d4_slow_osc, hw)

struct clk_slow_rc_osc {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	unsigned long frequency;
	unsigned long accuracy;
	unsigned long startup_usec;
};

#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)

struct clk_sam9x5_slow {
	struct clk_hw hw;
	void __iomem *sckcr;
	const struct clk_slow_bits *bits;
	u8 parent;
};

#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)

static int clk_slow_osc_prepare(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
	void __iomem *sckcr = osc->sckcr;
	u32 tmp = readl(sckcr);

	if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en))
		return 0;

	writel(tmp | osc->bits->cr_osc32en, sckcr);

	if (system_state < SYSTEM_RUNNING)
		udelay(osc->startup_usec);
	else
		usleep_range(osc->startup_usec, osc->startup_usec + 1);

	return 0;
}

static void clk_slow_osc_unprepare(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
	void __iomem *sckcr = osc->sckcr;
	u32 tmp = readl(sckcr);

	if (tmp & osc->bits->cr_osc32byp)
		return;

	writel(tmp & ~osc->bits->cr_osc32en, sckcr);
}

static int clk_slow_osc_is_prepared(struct clk_hw *hw)
{
	struct clk_slow_osc *osc = to_clk_slow_osc(hw);
	void __iomem *sckcr = osc->sckcr;
	u32 tmp = readl(sckcr);

	if (tmp & osc->bits->cr_osc32byp)
		return 1;

	return !!(tmp & osc->bits->cr_osc32en);
}

static const struct clk_ops slow_osc_ops = {

Annotation

Implementation Notes