drivers/mtd/nand/raw/ndfc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/mtd/nand/raw/ndfc.c
Extension
.c
Size
6861 bytes
Lines
277
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 ndfc_controller {
	struct platform_device *ofdev;
	void __iomem *ndfcbase;
	struct nand_chip chip;
	int chip_select;
	struct nand_controller ndfc_control;
};

static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];

static void ndfc_select_chip(struct nand_chip *nchip, int chip)
{
	uint32_t ccr;
	struct ndfc_controller *ndfc = nand_get_controller_data(nchip);

	ccr = ioread32be(ndfc->ndfcbase + NDFC_CCR);
	if (chip >= 0) {
		ccr &= ~NDFC_CCR_BS_MASK;
		ccr |= NDFC_CCR_BS(chip + ndfc->chip_select);
	} else
		ccr |= NDFC_CCR_RESET_CE;
	iowrite32be(ccr, ndfc->ndfcbase + NDFC_CCR);
}

static void ndfc_hwcontrol(struct nand_chip *chip, int cmd, unsigned int ctrl)
{
	struct ndfc_controller *ndfc = nand_get_controller_data(chip);

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_CLE)
		writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_CMD);
	else
		writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_ALE);
}

static int ndfc_ready(struct nand_chip *chip)
{
	struct ndfc_controller *ndfc = nand_get_controller_data(chip);

	return ioread32be(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
}

static void ndfc_enable_hwecc(struct nand_chip *chip, int mode)
{
	uint32_t ccr;
	struct ndfc_controller *ndfc = nand_get_controller_data(chip);

	ccr = ioread32be(ndfc->ndfcbase + NDFC_CCR);
	ccr |= NDFC_CCR_RESET_ECC;
	iowrite32be(ccr, ndfc->ndfcbase + NDFC_CCR);
	wmb();
}

static int ndfc_calculate_ecc(struct nand_chip *chip,
			      const u_char *dat, u_char *ecc_code)
{
	struct ndfc_controller *ndfc = nand_get_controller_data(chip);
	uint32_t ecc;
	uint8_t *p = (uint8_t *)&ecc;

	wmb();
	ecc = ioread32be(ndfc->ndfcbase + NDFC_ECC);
	/* The NDFC uses Smart Media (SMC) bytes order */
	ecc_code[0] = p[1];
	ecc_code[1] = p[2];
	ecc_code[2] = p[3];

	return 0;
}

/*
 * Speedups for buffer read/write/verify
 *
 * NDFC allows 32bit read/write of data. So we can speed up the buffer
 * functions. No further checking, as nand_base will always read/write
 * page aligned.
 */
static void ndfc_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
{
	struct ndfc_controller *ndfc = nand_get_controller_data(chip);
	uint32_t *p = (uint32_t *) buf;

	for(;len > 0; len -= 4)
		*p++ = ioread32be(ndfc->ndfcbase + NDFC_DATA);
}

static void ndfc_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
{

Annotation

Implementation Notes