drivers/mtd/hyperbus/rpc-if.c

Source file repositories/reference/linux-study-clean/drivers/mtd/hyperbus/rpc-if.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/hyperbus/rpc-if.c
Extension
.c
Size
4256 bytes
Lines
185
Domain
Driver Families
Bucket
drivers/mtd
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	rpcif_hyperbus {
	struct rpcif rpc;
	struct hyperbus_ctlr ctlr;
	struct hyperbus_device hbdev;
};

static const struct rpcif_op rpcif_op_tmpl = {
	.cmd = {
		.buswidth = 8,
		.ddr = true,
	},
	.ocmd = {
		.buswidth = 8,
		.ddr = true,
	},
	.addr = {
		.nbytes = 1,
		.buswidth = 8,
		.ddr = true,
	},
	.data = {
		.buswidth = 8,
		.ddr = true,
	},
};

static void rpcif_hb_prepare_read(struct rpcif *rpc, void *to,
				  unsigned long from, ssize_t len)
{
	struct rpcif_op op = rpcif_op_tmpl;

	op.cmd.opcode = HYPERBUS_RW_READ | HYPERBUS_AS_MEM;
	op.addr.val = from >> 1;
	op.dummy.buswidth = 1;
	op.dummy.ncycles = 15;
	op.data.dir = RPCIF_DATA_IN;
	op.data.nbytes = len;
	op.data.buf.in = to;

	rpcif_prepare(rpc->dev, &op, NULL, NULL);
}

static void rpcif_hb_prepare_write(struct rpcif *rpc, unsigned long to,
				   void *from, ssize_t len)
{
	struct rpcif_op op = rpcif_op_tmpl;

	op.cmd.opcode = HYPERBUS_RW_WRITE | HYPERBUS_AS_MEM;
	op.addr.val = to >> 1;
	op.data.dir = RPCIF_DATA_OUT;
	op.data.nbytes = len;
	op.data.buf.out = from;

	rpcif_prepare(rpc->dev, &op, NULL, NULL);
}

static u16 rpcif_hb_read16(struct hyperbus_device *hbdev, unsigned long addr)
{
	struct rpcif_hyperbus *hyperbus =
		container_of(hbdev, struct rpcif_hyperbus, hbdev);
	map_word data;

	rpcif_hb_prepare_read(&hyperbus->rpc, &data, addr, 2);

	rpcif_manual_xfer(hyperbus->rpc.dev);

	return data.x[0];
}

static void rpcif_hb_write16(struct hyperbus_device *hbdev, unsigned long addr,
			     u16 data)
{
	struct rpcif_hyperbus *hyperbus =
		container_of(hbdev, struct rpcif_hyperbus, hbdev);

	rpcif_hb_prepare_write(&hyperbus->rpc, addr, &data, 2);

	rpcif_manual_xfer(hyperbus->rpc.dev);
}

static void rpcif_hb_copy_from(struct hyperbus_device *hbdev, void *to,
			       unsigned long from, ssize_t len)
{
	struct rpcif_hyperbus *hyperbus =
		container_of(hbdev, struct rpcif_hyperbus, hbdev);

	rpcif_hb_prepare_read(&hyperbus->rpc, to, from, len);

	rpcif_dirmap_read(hyperbus->rpc.dev, from, len, to);
}

Annotation

Implementation Notes