drivers/clk/mvebu/common.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/mvebu/common.c
Extension
.c
Size
7009 bytes
Lines
297
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_gating_ctrl {
	spinlock_t *lock;
	struct clk **gates;
	int num_gates;
	void __iomem *base;
	u32 saved_reg;
};

static struct clk_gating_ctrl *ctrl;

static struct clk *clk_gating_get_src(
	struct of_phandle_args *clkspec, void *data)
{
	int n;

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

	for (n = 0; n < ctrl->num_gates; n++) {
		struct clk_gate *gate =
			to_clk_gate(__clk_get_hw(ctrl->gates[n]));
		if (clkspec->args[0] == gate->bit_idx)
			return ctrl->gates[n];
	}
	return ERR_PTR(-ENODEV);
}

static int mvebu_clk_gating_suspend(void *data)
{
	ctrl->saved_reg = readl(ctrl->base);
	return 0;
}

static void mvebu_clk_gating_resume(void *data)
{
	writel(ctrl->saved_reg, ctrl->base);
}

static const struct syscore_ops clk_gate_syscore_ops = {
	.suspend = mvebu_clk_gating_suspend,
	.resume = mvebu_clk_gating_resume,
};

static struct syscore clk_gate_syscore = {
	.ops = &clk_gate_syscore_ops,
};

void __init mvebu_clk_gating_setup(struct device_node *np,
				   const struct clk_gating_soc_desc *desc)
{
	struct clk *clk;
	void __iomem *base;
	const char *default_parent = NULL;
	int n;

	if (ctrl) {
		pr_err("mvebu-clk-gating: cannot instantiate more than one gateable clock device\n");
		return;
	}

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

	clk = of_clk_get(np, 0);
	if (!IS_ERR(clk)) {
		default_parent = __clk_get_name(clk);
		clk_put(clk);
	}

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

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

	ctrl->base = base;

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

	ctrl->num_gates = n;
	ctrl->gates = kzalloc_objs(*ctrl->gates, ctrl->num_gates);
	if (WARN_ON(!ctrl->gates))
		goto gates_out;

	for (n = 0; n < ctrl->num_gates; n++) {
		const char *parent =

Annotation

Implementation Notes