drivers/clk/tegra/clk-tegra-periph.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/tegra/clk-tegra-periph.c
Extension
.c
Size
44090 bytes
Lines
1031
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 pll_out_data {
	char *div_name;
	char *pll_out_name;
	u32 offset;
	int clk_id;
	u8 div_shift;
	u8 div_flags;
	u8 rst_shift;
	spinlock_t *lock;
};

#define PLL_OUT(_num, _offset, _div_shift, _div_flags, _rst_shift, _id) \
	{\
		.div_name = "pll_p_out" #_num "_div",\
		.pll_out_name = "pll_p_out" #_num,\
		.offset = _offset,\
		.div_shift = _div_shift,\
		.div_flags = _div_flags | TEGRA_DIVIDER_FIXED |\
					TEGRA_DIVIDER_ROUND_UP,\
		.rst_shift = _rst_shift,\
		.clk_id = tegra_clk_ ## _id,\
		.lock = &_offset ##_lock,\
	}

static struct pll_out_data pllp_out_clks[] = {
	PLL_OUT(1, PLLP_OUTA, 8, 0, 0, pll_p_out1),
	PLL_OUT(2, PLLP_OUTA, 24, 0, 16, pll_p_out2),
	PLL_OUT(2, PLLP_OUTA, 24, TEGRA_DIVIDER_INT, 16, pll_p_out2_int),
	PLL_OUT(3, PLLP_OUTB, 8, 0, 0, pll_p_out3),
	PLL_OUT(4, PLLP_OUTB, 24, 0, 16, pll_p_out4),
	PLL_OUT(5, PLLP_OUTC, 24, 0, 16, pll_p_out5),
};

static void __init periph_clk_init(void __iomem *clk_base,
				struct tegra_clk *tegra_clks)
{
	int i;
	struct clk *clk;
	struct clk **dt_clk;

	for (i = 0; i < ARRAY_SIZE(periph_clks); i++) {
		const struct tegra_clk_periph_regs *bank;
		struct tegra_periph_init_data *data;

		data = periph_clks + i;

		dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks);
		if (!dt_clk)
			continue;

		bank = get_reg_bank(data->periph.gate.clk_num);
		if (!bank)
			continue;

		data->periph.gate.regs = bank;
		clk = tegra_clk_register_periph_data(clk_base, data);
		*dt_clk = clk;
	}
}

static void __init gate_clk_init(void __iomem *clk_base,
				struct tegra_clk *tegra_clks)
{
	int i;
	struct clk *clk;
	struct clk **dt_clk;

	for (i = 0; i < ARRAY_SIZE(gate_clks); i++) {
		struct tegra_periph_init_data *data;

		data = gate_clks + i;

		dt_clk = tegra_lookup_dt_id(data->clk_id, tegra_clks);
		if (!dt_clk)
			continue;

		clk = tegra_clk_register_periph_gate(data->name,
				data->p.parent_name, data->periph.gate.flags,
				clk_base, data->flags,
				data->periph.gate.clk_num,
				periph_clk_enb_refcnt);
		*dt_clk = clk;
	}
}

static void __init div_clk_init(void __iomem *clk_base,
				struct tegra_clk *tegra_clks)
{
	int i;
	struct clk *clk;

Annotation

Implementation Notes