drivers/mtd/nand/raw/nand_hynix.c

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

File Facts

System
Linux kernel
Corpus path
drivers/mtd/nand/raw/nand_hynix.c
Extension
.c
Size
18204 bytes
Lines
748
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 hynix_read_retry {
	int nregs;
	const u8 *regs;
	u8 values[];
};

/**
 * struct hynix_nand - private Hynix NAND struct
 * @read_retry: read-retry information
 */
struct hynix_nand {
	const struct hynix_read_retry *read_retry;
};

/**
 * struct hynix_read_retry_otp - structure describing how the read-retry OTP
 *				 area
 * @nregs: number of hynix private registers to set before reading the reading
 *	   the OTP area
 * @regs: registers that should be configured
 * @values: values that should be set in regs
 * @page: the address to pass to the READ_PAGE command. Depends on the NAND
 *	  chip
 * @size: size of the read-retry OTP section
 */
struct hynix_read_retry_otp {
	int nregs;
	const u8 *regs;
	const u8 *values;
	int page;
	int size;
};

static bool hynix_nand_has_valid_jedecid(struct nand_chip *chip)
{
	u8 jedecid[5] = { };
	int ret;

	ret = nand_readid_op(chip, 0x40, jedecid, sizeof(jedecid));
	if (ret)
		return false;

	return !strncmp("JEDEC", jedecid, sizeof(jedecid));
}

static int hynix_nand_cmd_op(struct nand_chip *chip, u8 cmd)
{
	if (nand_has_exec_op(chip)) {
		struct nand_op_instr instrs[] = {
			NAND_OP_CMD(cmd, 0),
		};
		struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

		return nand_exec_op(chip, &op);
	}

	chip->legacy.cmdfunc(chip, cmd, -1, -1);

	return 0;
}

static int hynix_nand_reg_write_op(struct nand_chip *chip, u8 addr, u8 val)
{
	u16 column = ((u16)addr << 8) | addr;

	if (nand_has_exec_op(chip)) {
		struct nand_op_instr instrs[] = {
			NAND_OP_ADDR(1, &addr, 0),
			NAND_OP_8BIT_DATA_OUT(1, &val, 0),
		};
		struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);

		return nand_exec_op(chip, &op);
	}

	chip->legacy.cmdfunc(chip, NAND_CMD_NONE, column, -1);
	chip->legacy.write_byte(chip, val);

	return 0;
}

static int hynix_nand_setup_read_retry(struct nand_chip *chip, int retry_mode)
{
	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
	const u8 *values;
	int i, ret;

	values = hynix->read_retry->values +
		 (retry_mode * hynix->read_retry->nregs);

Annotation

Implementation Notes