drivers/clk/mvebu/kirkwood.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/mvebu/kirkwood.c
Extension
.c
Size
8619 bytes
Lines
359
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_muxing_soc_desc {
	const char *name;
	const char **parents;
	int num_parents;
	int shift;
	int width;
	unsigned long flags;
};

struct clk_muxing_ctrl {
	spinlock_t *lock;
	struct clk **muxes;
	int num_muxes;
};

static const char *powersave_parents[] = {
	"cpuclk",
	"ddrclk",
};

static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = {
	{ "powersave", powersave_parents, ARRAY_SIZE(powersave_parents),
		11, 1, 0 },
	{ }
};

static struct clk *clk_muxing_get_src(
	struct of_phandle_args *clkspec, void *data)
{
	struct clk_muxing_ctrl *ctrl = (struct clk_muxing_ctrl *)data;
	int n;

	if (clkspec->args_count < 1)
		return ERR_PTR(-EINVAL);

	for (n = 0; n < ctrl->num_muxes; n++) {
		struct clk_mux *mux =
			to_clk_mux(__clk_get_hw(ctrl->muxes[n]));
		if (clkspec->args[0] == mux->shift)
			return ctrl->muxes[n];
	}
	return ERR_PTR(-ENODEV);
}

static void __init kirkwood_clk_muxing_setup(struct device_node *np,
				   const struct clk_muxing_soc_desc *desc)
{
	struct clk_muxing_ctrl *ctrl;
	void __iomem *base;
	int n;

	base = of_iomap(np, 0);
	if (WARN_ON(!base))
		return;

	ctrl = kzalloc_obj(*ctrl);
	if (WARN_ON(!ctrl))
		goto ctrl_out;

	/* lock must already be initialized */
	ctrl->lock = &ctrl_gating_lock;

	/* Count, allocate, and register clock muxes */
	for (n = 0; desc[n].name;)
		n++;

	ctrl->num_muxes = n;
	ctrl->muxes = kzalloc_objs(struct clk *, ctrl->num_muxes);
	if (WARN_ON(!ctrl->muxes))
		goto muxes_out;

	for (n = 0; n < ctrl->num_muxes; n++) {
		ctrl->muxes[n] = clk_register_mux(NULL, desc[n].name,
				desc[n].parents, desc[n].num_parents,
				desc[n].flags, base, desc[n].shift,
				desc[n].width, desc[n].flags, ctrl->lock);
		WARN_ON(IS_ERR(ctrl->muxes[n]));
	}

	of_clk_add_provider(np, clk_muxing_get_src, ctrl);

	return;
muxes_out:
	kfree(ctrl);
ctrl_out:
	iounmap(base);
}

static void __init kirkwood_clk_init(struct device_node *np)
{

Annotation

Implementation Notes