drivers/mtd/nand/raw/loongson-nand-controller.c

Source file repositories/reference/linux-study-clean/drivers/mtd/nand/raw/loongson-nand-controller.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/nand/raw/loongson-nand-controller.c
Extension
.c
Size
28383 bytes
Lines
1025
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 loongson_nand_op {
	char addrs[LOONGSON_NAND_MAX_ADDR_CYC];
	unsigned int naddrs;
	unsigned int addrs_offset;
	unsigned int aligned_offset;
	unsigned int cmd_reg;
	unsigned int row_start;
	unsigned int rdy_timeout_ms;
	unsigned int orig_len;
	bool is_readid;
	bool is_erase;
	bool is_write;
	bool is_read;
	bool is_change_column;
	size_t len;
	char *buf;
};

struct loongson_nand_data {
	unsigned int max_id_cycle;
	unsigned int id_cycle_field;
	unsigned int status_field;
	unsigned int op_scope_field;
	unsigned int hold_cycle;
	unsigned int wait_cycle;
	unsigned int nand_cs;
	unsigned int dma_bits;
	int (*dma_config)(struct device *dev);
	void (*set_addr)(struct loongson_nand_host *host, struct loongson_nand_op *op);
};

struct loongson_nand_host {
	struct device *dev;
	struct nand_chip chip;
	struct nand_controller controller;
	const struct loongson_nand_data *data;
	unsigned int addr_cs_field;
	void __iomem *reg_base;
	struct regmap *regmap;
	/* DMA Engine stuff */
	dma_addr_t dma_base;
	struct dma_chan *dma_chan;
	dma_cookie_t dma_cookie;
	struct completion dma_complete;
};

static const struct regmap_config loongson_nand_regmap_config = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
};

static int loongson_nand_op_cmd_mapping(struct nand_chip *chip, struct loongson_nand_op *op,
					u8 opcode)
{
	struct loongson_nand_host *host = nand_get_controller_data(chip);

	op->row_start = chip->page_shift + 1;

	/* The controller abstracts the following NAND operations. */
	switch (opcode) {
	case NAND_CMD_STATUS:
		op->cmd_reg = LOONGSON_NAND_CMD_STATUS;
		break;
	case NAND_CMD_RESET:
		op->cmd_reg = LOONGSON_NAND_CMD_RESET;
		break;
	case NAND_CMD_READID:
		op->is_readid = true;
		op->cmd_reg = LOONGSON_NAND_CMD_READID;
		break;
	case NAND_CMD_ERASE1:
		op->is_erase = true;
		op->addrs_offset = LOONGSON_NAND_COL_ADDR_CYC;
		break;
	case NAND_CMD_ERASE2:
		if (!op->is_erase)
			return -EOPNOTSUPP;
		/* During erasing, row_start differs from the default value. */
		op->row_start = chip->page_shift;
		op->cmd_reg = LOONGSON_NAND_CMD_ERASE;
		break;
	case NAND_CMD_SEQIN:
		op->is_write = true;
		break;
	case NAND_CMD_PAGEPROG:
		if (!op->is_write)
			return -EOPNOTSUPP;
		op->cmd_reg = LOONGSON_NAND_CMD_WRITE;
		break;

Annotation

Implementation Notes