drivers/memory/renesas-rpc-if.c

Source file repositories/reference/linux-study-clean/drivers/memory/renesas-rpc-if.c

File Facts

System
Linux kernel
Corpus path
drivers/memory/renesas-rpc-if.c
Extension
.c
Size
30121 bytes
Lines
1170
Domain
Driver Families
Bucket
drivers/memory
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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_impl {
	int (*hw_init)(struct rpcif_priv *rpc, bool hyperflash);
	void (*prepare)(struct rpcif_priv *rpc, const struct rpcif_op *op,
			u64 *offs, size_t *len);
	int (*manual_xfer)(struct rpcif_priv *rpc);
	size_t (*dirmap_read)(struct rpcif_priv *rpc, u64 offs, size_t len,
			      void *buf);
	u32 status_reg;
	u32 status_mask;
};

struct rpcif_info {
	const struct regmap_config *regmap_config;
	const struct rpcif_impl *impl;
	enum rpcif_type type;
	u8 strtim;
};

struct rpcif_priv {
	struct device *dev;
	void __iomem *base;
	void __iomem *dirmap;
	struct regmap *regmap;
	struct reset_control *rstc;
	struct clk *spi_clk;
	struct clk *spix2_clk;
	struct platform_device *vdev;
	size_t size;
	const struct rpcif_info *info;
	enum rpcif_data_dir dir;
	u8 bus_size;
	u8 xfer_size;
	u8 addr_nbytes;		/* Specified for xSPI */
	u32 proto;		/* Specified for xSPI */
	void *buffer;
	u32 xferlen;
	u32 smcr;
	u32 smadr;
	u32 command;		/* DRCMR or SMCMR */
	u32 option;		/* DROPR or SMOPR */
	u32 enable;		/* DRENR or SMENR */
	u32 dummy;		/* DRDMCR or SMDMCR */
	u32 ddr;		/* DRDRENR or SMDRENR */
};

/*
 * Custom accessor functions to ensure SM[RW]DR[01] are always accessed with
 * proper width.  Requires rpcif_priv.xfer_size to be correctly set before!
 */
static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val)
{
	struct rpcif_priv *rpc = context;

	switch (reg) {
	case RPCIF_SMRDR0:
	case RPCIF_SMWDR0:
		switch (rpc->xfer_size) {
		case 1:
			*val = readb(rpc->base + reg);
			return 0;

		case 2:
			*val = readw(rpc->base + reg);
			return 0;

		case 4:
		case 8:
			*val = readl(rpc->base + reg);
			return 0;

		default:
			return -EILSEQ;
		}

	case RPCIF_SMRDR1:
	case RPCIF_SMWDR1:
		if (rpc->xfer_size != 8)
			return -EILSEQ;
		break;
	}

	*val = readl(rpc->base + reg);
	return 0;
}

static int rpcif_reg_write(void *context, unsigned int reg, unsigned int val)
{
	struct rpcif_priv *rpc = context;

	switch (reg) {

Annotation

Implementation Notes