drivers/clk/tegra/clk-bpmp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/tegra/clk-bpmp.c
Extension
.c
Size
16908 bytes
Lines
706
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 tegra_bpmp_clk_info {
	unsigned int id;
	char name[MRQ_CLK_NAME_MAXLEN];
	unsigned int parents[MRQ_CLK_MAX_PARENTS];
	unsigned int num_parents;
	unsigned long flags;
};

struct tegra_bpmp_clk {
	struct clk_hw hw;

	struct tegra_bpmp *bpmp;
	unsigned int id;

	unsigned int num_parents;
	unsigned int *parents;
};

static inline struct tegra_bpmp_clk *to_tegra_bpmp_clk(struct clk_hw *hw)
{
	return container_of(hw, struct tegra_bpmp_clk, hw);
}

struct tegra_bpmp_clk_message {
	unsigned int cmd;
	unsigned int id;

	struct {
		const void *data;
		size_t size;
	} tx;

	struct {
		void *data;
		size_t size;
		int ret;
	} rx;
};

static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
				   const struct tegra_bpmp_clk_message *clk)
{
	struct mrq_clk_request request;
	struct tegra_bpmp_message msg;
	void *req = &request;
	int err;

	memset(&request, 0, sizeof(request));
	request.cmd_and_id = (clk->cmd << 24) | clk->id;

	/*
	 * The mrq_clk_request structure has an anonymous union at offset 4
	 * that contains all possible sub-command structures. Copy the data
	 * to that union. Ideally we'd be able to refer to it by name, but
	 * doing so would require changing the ABI header and increase the
	 * maintenance burden.
	 */
	memcpy(req + 4, clk->tx.data, clk->tx.size);

	memset(&msg, 0, sizeof(msg));
	msg.mrq = MRQ_CLK;
	msg.tx.data = &request;
	msg.tx.size = sizeof(request);
	msg.rx.data = clk->rx.data;
	msg.rx.size = clk->rx.size;

	err = tegra_bpmp_transfer(bpmp, &msg);
	if (err < 0)
		return err;
	else if (msg.rx.ret < 0)
		return -EINVAL;

	return 0;
}

static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
	struct tegra_bpmp_clk_message msg;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = CMD_CLK_ENABLE;
	msg.id = clk->id;

	return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
}

static void tegra_bpmp_clk_unprepare(struct clk_hw *hw)
{
	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);

Annotation

Implementation Notes