// SPDX-License-Identifier: GPL-2.0 OR MIT
/*
 * Rockchip NAND Flash controller driver.
 * Copyright (C) 2020 Rockchip Inc.
 * Author: Yifeng Zhao <yifeng.zhao@rock-chips.com>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

/*
 * NFC Page Data Layout:
 *	1024 bytes data + 4Bytes sys data + 28Bytes~124Bytes ECC data +
 *	1024 bytes data + 4Bytes sys data + 28Bytes~124Bytes ECC data +
 *	......
 * NAND Page Data Layout:
 *	1024 * n data + m Bytes oob
 * Original Bad Block Mask Location:
 *	First byte of oob(spare).
 * nand_chip->oob_poi data layout:
 *	4Bytes sys data + .... + 4Bytes sys data + ECC data.
 */

/* NAND controller register definition */
#define NFC_READ			(0)
#define NFC_WRITE			(1)

#define NFC_FMCTL			(0x00)
#define   FMCTL_CE_SEL_M		0xFF
#define   FMCTL_CE_SEL(x)		(1 << (x))
#define   FMCTL_WP			BIT(8)
#define   FMCTL_RDY			BIT(9)

#define NFC_FMWAIT			(0x04)
#define   FLCTL_RST			BIT(0)
#define   FLCTL_WR			(1)	/* 0: read, 1: write */
#define   FLCTL_XFER_ST			BIT(2)
#define   FLCTL_XFER_EN			BIT(3)
#define   FLCTL_ACORRECT		BIT(10) /* Auto correct error bits. */
#define   FLCTL_XFER_READY		BIT(20)
#define   FLCTL_XFER_SECTOR		(22)
#define   FLCTL_TOG_FIX			BIT(29)

#define   BCHCTL_BANK_M			(7 << 5)
#define   BCHCTL_BANK			(5)

#define   DMA_ST			BIT(0)
#define   DMA_WR			(1)	/* 0: write, 1: read */
#define   DMA_EN			BIT(2)
#define   DMA_AHB_SIZE			(3)	/* 0: 1, 1: 2, 2: 4 */
#define   DMA_BURST_SIZE		(6)	/* 0: 1, 3: 4, 5: 8, 7: 16 */
#define   DMA_INC_NUM			(9)	/* 1 - 16 */

#define ECC_ERR_CNT(x, e) ((((x) >> (e).low) & (e).low_mask) |\
	  (((x) >> (e).high) & (e).high_mask) << (e).low_bn)
#define   INT_DMA			BIT(0)
#define NFC_BANK			(0x800)
#define NFC_BANK_STEP			(0x100)
#define   BANK_DATA			(0x00)
#define   BANK_ADDR			(0x04)
#define   BANK_CMD			(0x08)
#define NFC_SRAM0			(0x1000)
#define NFC_SRAM1			(0x1400)
#define NFC_SRAM_SIZE			(0x400)
#define NFC_TIMEOUT			(500000)
#define NFC_MAX_OOB_PER_STEP		128
#define NFC_MIN_OOB_PER_STEP		64
#define MAX_DATA_SIZE			0xFFFC
#define MAX_ADDRESS_CYC			6
#define NFC_ECC_MAX_MODES		4
#define NFC_MAX_NSELS			(8) /* Some Socs only have 1 or 2 CSs. */
#define NFC_SYS_DATA_SIZE		(4) /* 4 bytes sys data in oob pre 1024 data.*/
#define RK_DEFAULT_CLOCK_RATE		(150 * 1000 * 1000) /* 150 Mhz */
#define ACCTIMING(csrw, rwpw, rwcs)	((csrw) << 12 | (rwpw) << 5 | (rwcs))

enum nfc_type {
	NFC_V6,
	NFC_V8,
	NFC_V9,
};

/**
 * struct rk_ecc_cnt_status: represent a ecc status data.
 * @err_flag_bit: error flag bit index at register.
 * @low: ECC count low bit index at register.
 * @low_mask: mask bit.
 * @low_bn: ECC count low bit number.
 * @high: ECC count high bit index at register.
 * @high_mask: mask bit
 */
struct ecc_cnt_status {
	u8 err_flag_bit;
	u8 low;
	u8 low_mask;
	u8 low_bn;
	u8 high;
	u8 high_mask;
};

/**
 * @type: NFC version
 * @ecc_strengths: ECC strengths
 * @ecc_cfgs: ECC config values
 * @flctl_off: FLCTL register offset
 * @bchctl_off: BCHCTL register offset
 * @dma_data_buf_off: DMA_DATA_BUF register offset
 * @dma_oob_buf_off: DMA_OOB_BUF register offset
 * @dma_cfg_off: DMA_CFG register offset
 * @dma_st_off: DMA_ST register offset
 * @bch_st_off: BCG_ST register offset
 * @randmz_off: RANDMZ register offset
 * @int_en_off: interrupt enable register offset
 * @int_clr_off: interrupt clean register offset
 * @int_st_off: interrupt status register offset
 * @oob0_off: oob0 register offset
 * @oob1_off: oob1 register offset
 * @ecc0: represent ECC0 status data
 * @ecc1: represent ECC1 status data
 */
struct nfc_cfg {
	enum nfc_type type;
	u8 ecc_strengths[NFC_ECC_MAX_MODES];
	u32 ecc_cfgs[NFC_ECC_MAX_MODES];
	u32 flctl_off;
	u32 bchctl_off;
	u32 dma_cfg_off;
	u32 dma_data_buf_off;
	u32 dma_oob_buf_off;
	u32 dma_st_off;
	u32 bch_st_off;
	u32 randmz_off;
	u32 int_en_off;
	u32 int_clr_off;
	u32 int_st_off;
	u32 oob0_off;
	u32 oob1_off;
	struct ecc_cnt_status ecc0;
	struct ecc_cnt_status ecc1;
};

struct rk_nfc_nand_chip {
	struct list_head node;
	struct nand_chip chip;

	u16 boot_blks;
	u16 metadata_size;
	u32 boot_ecc;
	u32 timing;

	u8 nsels;
	u8 sels[];
	/* Nothing after this field. */
};

struct rk_nfc {
	struct nand_controller controller;
	const struct nfc_cfg *cfg;
	struct device *dev;

	struct clk *nfc_clk;
	struct clk *ahb_clk;
	void __iomem *regs;

	u32 selected_bank;
	u32 band_offset;
	u32 cur_ecc;
	u32 cur_timing;

	struct completion done;
	struct list_head chips;

	u8 *page_buf;
	u32 *oob_buf;
	u32 page_buf_size;
	u32 oob_buf_size;

	unsigned long assigned_cs;
};

static inline struct rk_nfc_nand_chip *rk_nfc_to_rknand(struct nand_chip *chip)
{
	return container_of(chip, struct rk_nfc_nand_chip, chip);
}

static inline u8 *rk_nfc_buf_to_data_ptr(struct nand_chip *chip, const u8 *p, int i)
{
	return (u8 *)p + i * chip->ecc.size;
}

static inline u8 *rk_nfc_buf_to_oob_ptr(struct nand_chip *chip, int i)
{
	u8 *poi;

	poi = chip->oob_poi + i * NFC_SYS_DATA_SIZE;

	return poi;
}

static inline u8 *rk_nfc_buf_to_oob_ecc_ptr(struct nand_chip *chip, int i)
{
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	u8 *poi;

	poi = chip->oob_poi + rknand->metadata_size + chip->ecc.bytes * i;

	return poi;
}

static inline int rk_nfc_data_len(struct nand_chip *chip)
{
	return chip->ecc.size + chip->ecc.bytes + NFC_SYS_DATA_SIZE;
}

static inline u8 *rk_nfc_data_ptr(struct nand_chip *chip, int i)
{
	struct rk_nfc *nfc = nand_get_controller_data(chip);

	return nfc->page_buf + i * rk_nfc_data_len(chip);
}

static inline u8 *rk_nfc_oob_ptr(struct nand_chip *chip, int i)
{
	struct rk_nfc *nfc = nand_get_controller_data(chip);

	return nfc->page_buf + i * rk_nfc_data_len(chip) + chip->ecc.size;
}

static int rk_nfc_hw_ecc_setup(struct nand_chip *chip, u32 strength)
{
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	u32 reg, i;

	for (i = 0; i < NFC_ECC_MAX_MODES; i++) {
		if (strength == nfc->cfg->ecc_strengths[i]) {
			reg = nfc->cfg->ecc_cfgs[i];
			break;
		}
	}

	if (i >= NFC_ECC_MAX_MODES)
		return -EINVAL;

	writel(reg, nfc->regs + nfc->cfg->bchctl_off);

	/* Save chip ECC setting */
	nfc->cur_ecc = strength;

	return 0;
}

static void rk_nfc_select_chip(struct nand_chip *chip, int cs)
{
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	u32 val;

	if (cs < 0) {
		nfc->selected_bank = -1;
		/* Deselect the currently selected target. */
		val = readl_relaxed(nfc->regs + NFC_FMCTL);
		val &= ~FMCTL_CE_SEL_M;
		writel(val, nfc->regs + NFC_FMCTL);
		return;
	}

	nfc->selected_bank = rknand->sels[cs];
	nfc->band_offset = NFC_BANK + nfc->selected_bank * NFC_BANK_STEP;

	val = readl_relaxed(nfc->regs + NFC_FMCTL);
	val &= ~FMCTL_CE_SEL_M;
	val |= FMCTL_CE_SEL(nfc->selected_bank);

	writel(val, nfc->regs + NFC_FMCTL);

	/*
	 * Compare current chip timing with selected chip timing and
	 * change if needed.
	 */
	if (nfc->cur_timing != rknand->timing) {
		writel(rknand->timing, nfc->regs + NFC_FMWAIT);
		nfc->cur_timing = rknand->timing;
	}

	/*
	 * Compare current chip ECC setting with selected chip ECC setting and
	 * change if needed.
	 */
	if (nfc->cur_ecc != ecc->strength)
		rk_nfc_hw_ecc_setup(chip, ecc->strength);
}

static inline int rk_nfc_wait_ioready(struct rk_nfc *nfc)
{
	int rc;
	u32 val;

	rc = readl_relaxed_poll_timeout(nfc->regs + NFC_FMCTL, val,
					val & FMCTL_RDY, 10, NFC_TIMEOUT);

	return rc;
}

static void rk_nfc_read_buf(struct rk_nfc *nfc, u8 *buf, int len)
{
	int i;

	for (i = 0; i < len; i++)
		buf[i] = readb_relaxed(nfc->regs + nfc->band_offset +
				       BANK_DATA);
}

static void rk_nfc_write_buf(struct rk_nfc *nfc, const u8 *buf, int len)
{
	int i;

	for (i = 0; i < len; i++)
		writeb(buf[i], nfc->regs + nfc->band_offset + BANK_DATA);
}

static int rk_nfc_cmd(struct nand_chip *chip,
		      const struct nand_subop *subop)
{
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	unsigned int i, j, remaining, start;
	int reg_offset = nfc->band_offset;
	u8 *inbuf = NULL;
	const u8 *outbuf;
	u32 cnt = 0;
	int ret = 0;

	for (i = 0; i < subop->ninstrs; i++) {
		const struct nand_op_instr *instr = &subop->instrs[i];

		switch (instr->type) {
		case NAND_OP_CMD_INSTR:
			writeb(instr->ctx.cmd.opcode,
			       nfc->regs + reg_offset + BANK_CMD);
			break;

		case NAND_OP_ADDR_INSTR:
			remaining = nand_subop_get_num_addr_cyc(subop, i);
			start = nand_subop_get_addr_start_off(subop, i);

			for (j = 0; j < 8 && j + start < remaining; j++)
				writeb(instr->ctx.addr.addrs[j + start],
				       nfc->regs + reg_offset + BANK_ADDR);
			break;

		case NAND_OP_DATA_IN_INSTR:
		case NAND_OP_DATA_OUT_INSTR:
			start = nand_subop_get_data_start_off(subop, i);
			cnt = nand_subop_get_data_len(subop, i);

			if (instr->type == NAND_OP_DATA_OUT_INSTR) {
				outbuf = instr->ctx.data.buf.out + start;
				rk_nfc_write_buf(nfc, outbuf, cnt);
			} else {
				inbuf = instr->ctx.data.buf.in + start;
				rk_nfc_read_buf(nfc, inbuf, cnt);
			}
			break;

		case NAND_OP_WAITRDY_INSTR:
			if (rk_nfc_wait_ioready(nfc) < 0) {
				ret = -ETIMEDOUT;
				dev_err(nfc->dev, "IO not ready\n");
			}
			break;
		}
	}

	return ret;
}

static const struct nand_op_parser rk_nfc_op_parser = NAND_OP_PARSER(
	NAND_OP_PARSER_PATTERN(
		rk_nfc_cmd,
		NAND_OP_PARSER_PAT_CMD_ELEM(true),
		NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC),
		NAND_OP_PARSER_PAT_CMD_ELEM(true),
		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
		NAND_OP_PARSER_PAT_DATA_IN_ELEM(true, MAX_DATA_SIZE)),
	NAND_OP_PARSER_PATTERN(
		rk_nfc_cmd,
		NAND_OP_PARSER_PAT_CMD_ELEM(true),
		NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYC),
		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(true, MAX_DATA_SIZE),
		NAND_OP_PARSER_PAT_CMD_ELEM(true),
		NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)),
);

static int rk_nfc_exec_op(struct nand_chip *chip,
			  const struct nand_operation *op,
			  bool check_only)
{
	if (!check_only)
		rk_nfc_select_chip(chip, op->cs);

	return nand_op_parser_exec_op(chip, &rk_nfc_op_parser, op,
				      check_only);
}

static int rk_nfc_setup_interface(struct nand_chip *chip, int target,
				  const struct nand_interface_config *conf)
{
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	const struct nand_sdr_timings *timings;
	u32 rate, tc2rw, trwpw, trw2c;
	u32 temp;

	if (target < 0)
		return 0;

	timings = nand_get_sdr_timings(conf);
	if (IS_ERR(timings))
		return -EOPNOTSUPP;

	if (IS_ERR(nfc->nfc_clk))
		rate = clk_get_rate(nfc->ahb_clk);
	else
		rate = clk_get_rate(nfc->nfc_clk);

	/* Turn clock rate into kHz. */
	rate /= 1000;

	tc2rw = 1;
	trw2c = 1;

	trwpw = max(timings->tWC_min, timings->tRC_min) / 1000;
	trwpw = DIV_ROUND_UP(trwpw * rate, 1000000);

	temp = timings->tREA_max / 1000;
	temp = DIV_ROUND_UP(temp * rate, 1000000);

	if (trwpw < temp)
		trwpw = temp;

	/*
	 * ACCON: access timing control register
	 * -------------------------------------
	 * 31:18: reserved
	 * 17:12: csrw, clock cycles from the falling edge of CSn to the
	 *   falling edge of RDn or WRn
	 * 11:11: reserved
	 * 10:05: rwpw, the width of RDn or WRn in processor clock cycles
	 * 04:00: rwcs, clock cycles from the rising edge of RDn or WRn to the
	 *   rising edge of CSn
	 */

	/* Save chip timing */
	rknand->timing = ACCTIMING(tc2rw, trwpw, trw2c);

	return 0;
}

static void rk_nfc_xfer_start(struct rk_nfc *nfc, u8 rw, u8 n_KB,
			      dma_addr_t dma_data, dma_addr_t dma_oob)
{
	u32 dma_reg, fl_reg, bch_reg;

	dma_reg = DMA_ST | ((!rw) << DMA_WR) | DMA_EN | (2 << DMA_AHB_SIZE) |
	      (7 << DMA_BURST_SIZE) | (16 << DMA_INC_NUM);

	fl_reg = (rw << FLCTL_WR) | FLCTL_XFER_EN | FLCTL_ACORRECT |
		 (n_KB << FLCTL_XFER_SECTOR) | FLCTL_TOG_FIX;

	if (nfc->cfg->type == NFC_V6 || nfc->cfg->type == NFC_V8) {
		bch_reg = readl_relaxed(nfc->regs + nfc->cfg->bchctl_off);
		bch_reg = (bch_reg & (~BCHCTL_BANK_M)) |
			  (nfc->selected_bank << BCHCTL_BANK);
		writel(bch_reg, nfc->regs + nfc->cfg->bchctl_off);
	}

	writel(dma_reg, nfc->regs + nfc->cfg->dma_cfg_off);
	writel((u32)dma_data, nfc->regs + nfc->cfg->dma_data_buf_off);
	writel((u32)dma_oob, nfc->regs + nfc->cfg->dma_oob_buf_off);
	writel(fl_reg, nfc->regs + nfc->cfg->flctl_off);
	fl_reg |= FLCTL_XFER_ST;
	writel(fl_reg, nfc->regs + nfc->cfg->flctl_off);
}

static int rk_nfc_wait_for_xfer_done(struct rk_nfc *nfc)
{
	void __iomem *ptr;
	u32 reg;

	ptr = nfc->regs + nfc->cfg->flctl_off;

	return readl_relaxed_poll_timeout(ptr, reg,
					 reg & FLCTL_XFER_READY,
					 10, NFC_TIMEOUT);
}

static int rk_nfc_write_page_raw(struct nand_chip *chip, const u8 *buf,
				 int oob_on, int page)
{
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	int i, pages_per_blk;

	pages_per_blk = mtd->erasesize / mtd->writesize;
	if ((chip->options & NAND_IS_BOOT_MEDIUM) &&
	    (page < (pages_per_blk * rknand->boot_blks)) &&
	    rknand->boot_ecc != ecc->strength) {
		/*
		 * There's currently no method to notify the MTD framework that
		 * a different ECC strength is in use for the boot blocks.
		 */
		return -EIO;
	}

	if (!buf)
		memset(nfc->page_buf, 0xff, mtd->writesize + mtd->oobsize);

	for (i = 0; i < ecc->steps; i++) {
		/* Copy data to the NFC buffer. */
		if (buf)
			memcpy(rk_nfc_data_ptr(chip, i),
			       rk_nfc_buf_to_data_ptr(chip, buf, i),
			       ecc->size);
		/*
		 * The first four bytes of OOB are reserved for the
		 * boot ROM. In some debugging cases, such as with a
		 * read, erase and write back test these 4 bytes stored
		 * in OOB also need to be written back.
		 *
		 * The function nand_block_bad detects bad blocks like:
		 *
		 * bad = chip->oob_poi[chip->badblockpos];
		 *
		 * chip->badblockpos == 0 for a large page NAND Flash,
		 * so chip->oob_poi[0] is the bad block mask (BBM).
		 *
		 * The OOB data layout on the NFC is:
		 *
		 *    PA0  PA1  PA2  PA3  | BBM OOB1 OOB2 OOB3 | ...
		 *
		 * or
		 *
		 *    0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
		 *
		 * The code here just swaps the first 4 bytes with the last
		 * 4 bytes without losing any data.
		 *
		 * The chip->oob_poi data layout:
		 *
		 *    BBM  OOB1 OOB2 OOB3 |......|  PA0  PA1  PA2  PA3
		 *
		 * The rk_nfc_ooblayout_free() function already has reserved
		 * these 4 bytes with:
		 *
		 * oob_region->offset = NFC_SYS_DATA_SIZE + 2;
		 */
		if (!i)
			memcpy(rk_nfc_oob_ptr(chip, i),
			       rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1),
			       NFC_SYS_DATA_SIZE);
		else
			memcpy(rk_nfc_oob_ptr(chip, i),
			       rk_nfc_buf_to_oob_ptr(chip, i - 1),
			       NFC_SYS_DATA_SIZE);
		/* Copy ECC data to the NFC buffer. */
		memcpy(rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE,
		       rk_nfc_buf_to_oob_ecc_ptr(chip, i),
		       ecc->bytes);
	}

	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
	rk_nfc_write_buf(nfc, buf, mtd->writesize + mtd->oobsize);
	return nand_prog_page_end_op(chip);
}

static int rk_nfc_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
				   int oob_on, int page)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP :
			NFC_MIN_OOB_PER_STEP;
	int pages_per_blk = mtd->erasesize / mtd->writesize;
	int ret = 0, i, boot_rom_mode = 0;
	dma_addr_t dma_data, dma_oob;
	u32 reg;
	u8 *oob;

	nand_prog_page_begin_op(chip, page, 0, NULL, 0);

	if (buf)
		memcpy(nfc->page_buf, buf, mtd->writesize);
	else
		memset(nfc->page_buf, 0xFF, mtd->writesize);

	/*
	 * The first blocks (4, 8 or 16 depending on the device) are used
	 * by the boot ROM and the first 32 bits of OOB need to link to
	 * the next page address in the same block. We can't directly copy
	 * OOB data from the MTD framework, because this page address
	 * conflicts for example with the bad block marker (BBM),
	 * so we shift all OOB data including the BBM with 4 byte positions.
	 * As a consequence the OOB size available to the MTD framework is
	 * also reduced with 4 bytes.
	 *
	 *    PA0  PA1  PA2  PA3 | BBM OOB1 OOB2 OOB3 | ...
	 *
	 * If a NAND is not a boot medium or the page is not a boot block,
	 * the first 4 bytes are left untouched by writing 0xFF to them.
	 *
	 *   0xFF 0xFF 0xFF 0xFF | BBM OOB1 OOB2 OOB3 | ...
	 *
	 * Configure the ECC algorithm supported by the boot ROM.
	 */
	if ((page < (pages_per_blk * rknand->boot_blks)) &&
	    (chip->options & NAND_IS_BOOT_MEDIUM)) {
		boot_rom_mode = 1;
		if (rknand->boot_ecc != ecc->strength)
			rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc);
	}

	for (i = 0; i < ecc->steps; i++) {
		if (!i) {
			reg = 0xFFFFFFFF;
		} else {
			oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
			reg = oob[0] | oob[1] << 8 | oob[2] << 16 |
			      oob[3] << 24;
		}

		if (!i && boot_rom_mode)
			reg = (page & (pages_per_blk - 1)) * 4;

		if (nfc->cfg->type == NFC_V9)
			nfc->oob_buf[i] = reg;
		else
			nfc->oob_buf[i * (oob_step / 4)] = reg;
	}

	dma_data = dma_map_single(nfc->dev, (void *)nfc->page_buf,
				  mtd->writesize, DMA_TO_DEVICE);
	dma_oob = dma_map_single(nfc->dev, nfc->oob_buf,
				 ecc->steps * oob_step,
				 DMA_TO_DEVICE);

	reinit_completion(&nfc->done);
	writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off);

	rk_nfc_xfer_start(nfc, NFC_WRITE, ecc->steps, dma_data,
			  dma_oob);
	ret = wait_for_completion_timeout(&nfc->done,
					  msecs_to_jiffies(100));
	if (!ret)
		dev_warn(nfc->dev, "write: wait dma done timeout.\n");
	/*
	 * Whether the DMA transfer is completed or not. The driver
	 * needs to check the NFC`s status register to see if the data
	 * transfer was completed.
	 */
	ret = rk_nfc_wait_for_xfer_done(nfc);

	dma_unmap_single(nfc->dev, dma_data, mtd->writesize,
			 DMA_TO_DEVICE);
	dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step,
			 DMA_TO_DEVICE);

	if (boot_rom_mode && rknand->boot_ecc != ecc->strength)
		rk_nfc_hw_ecc_setup(chip, ecc->strength);

	if (ret) {
		dev_err(nfc->dev, "write: wait transfer done timeout.\n");
		return -ETIMEDOUT;
	}

	return nand_prog_page_end_op(chip);
}

static int rk_nfc_write_oob(struct nand_chip *chip, int page)
{
	return rk_nfc_write_page_hwecc(chip, NULL, 1, page);
}

static int rk_nfc_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_on,
				int page)
{
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	int i, pages_per_blk;

	pages_per_blk = mtd->erasesize / mtd->writesize;
	if ((chip->options & NAND_IS_BOOT_MEDIUM) &&
	    (page < (pages_per_blk * rknand->boot_blks)) &&
	    rknand->boot_ecc != ecc->strength) {
		/*
		 * There's currently no method to notify the MTD framework that
		 * a different ECC strength is in use for the boot blocks.
		 */
		return -EIO;
	}

	nand_read_page_op(chip, page, 0, NULL, 0);
	rk_nfc_read_buf(nfc, nfc->page_buf, mtd->writesize + mtd->oobsize);
	for (i = 0; i < ecc->steps; i++) {
		/*
		 * The first four bytes of OOB are reserved for the
		 * boot ROM. In some debugging cases, such as with a read,
		 * erase and write back test, these 4 bytes also must be
		 * saved somewhere, otherwise this information will be
		 * lost during a write back.
		 */
		if (!i)
			memcpy(rk_nfc_buf_to_oob_ptr(chip, ecc->steps - 1),
			       rk_nfc_oob_ptr(chip, i),
			       NFC_SYS_DATA_SIZE);
		else
			memcpy(rk_nfc_buf_to_oob_ptr(chip, i - 1),
			       rk_nfc_oob_ptr(chip, i),
			       NFC_SYS_DATA_SIZE);

		/* Copy ECC data from the NFC buffer. */
		memcpy(rk_nfc_buf_to_oob_ecc_ptr(chip, i),
		       rk_nfc_oob_ptr(chip, i) + NFC_SYS_DATA_SIZE,
		       ecc->bytes);

		/* Copy data from the NFC buffer. */
		if (buf)
			memcpy(rk_nfc_buf_to_data_ptr(chip, buf, i),
			       rk_nfc_data_ptr(chip, i),
			       ecc->size);
	}

	return 0;
}

static int rk_nfc_read_page_hwecc(struct nand_chip *chip, u8 *buf, int oob_on,
				  int page)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	int oob_step = (ecc->bytes > 60) ? NFC_MAX_OOB_PER_STEP :
			NFC_MIN_OOB_PER_STEP;
	int pages_per_blk = mtd->erasesize / mtd->writesize;
	dma_addr_t dma_data, dma_oob;
	int ret = 0, i, cnt, boot_rom_mode = 0;
	int max_bitflips = 0, bch_st, ecc_fail = 0;
	u8 *oob;
	u32 tmp;

	nand_read_page_op(chip, page, 0, NULL, 0);

	dma_data = dma_map_single(nfc->dev, nfc->page_buf,
				  mtd->writesize,
				  DMA_FROM_DEVICE);
	dma_oob = dma_map_single(nfc->dev, nfc->oob_buf,
				 ecc->steps * oob_step,
				 DMA_FROM_DEVICE);

	/*
	 * The first blocks (4, 8 or 16 depending on the device)
	 * are used by the boot ROM.
	 * Configure the ECC algorithm supported by the boot ROM.
	 */
	if ((page < (pages_per_blk * rknand->boot_blks)) &&
	    (chip->options & NAND_IS_BOOT_MEDIUM)) {
		boot_rom_mode = 1;
		if (rknand->boot_ecc != ecc->strength)
			rk_nfc_hw_ecc_setup(chip, rknand->boot_ecc);
	}

	reinit_completion(&nfc->done);
	writel(INT_DMA, nfc->regs + nfc->cfg->int_en_off);
	rk_nfc_xfer_start(nfc, NFC_READ, ecc->steps, dma_data,
			  dma_oob);
	ret = wait_for_completion_timeout(&nfc->done,
					  msecs_to_jiffies(100));
	if (!ret)
		dev_warn(nfc->dev, "read: wait dma done timeout.\n");
	/*
	 * Whether the DMA transfer is completed or not. The driver
	 * needs to check the NFC`s status register to see if the data
	 * transfer was completed.
	 */
	ret = rk_nfc_wait_for_xfer_done(nfc);

	dma_unmap_single(nfc->dev, dma_data, mtd->writesize,
			 DMA_FROM_DEVICE);
	dma_unmap_single(nfc->dev, dma_oob, ecc->steps * oob_step,
			 DMA_FROM_DEVICE);

	if (ret) {
		ret = -ETIMEDOUT;
		dev_err(nfc->dev, "read: wait transfer done timeout.\n");
		goto timeout_err;
	}

	for (i = 1; i < ecc->steps; i++) {
		oob = chip->oob_poi + (i - 1) * NFC_SYS_DATA_SIZE;
		if (nfc->cfg->type == NFC_V9)
			tmp = nfc->oob_buf[i];
		else
			tmp = nfc->oob_buf[i * (oob_step / 4)];
		*oob++ = (u8)tmp;
		*oob++ = (u8)(tmp >> 8);
		*oob++ = (u8)(tmp >> 16);
		*oob++ = (u8)(tmp >> 24);
	}

	for (i = 0; i < (ecc->steps / 2); i++) {
		bch_st = readl_relaxed(nfc->regs +
				       nfc->cfg->bch_st_off + i * 4);
		if (bch_st & BIT(nfc->cfg->ecc0.err_flag_bit) ||
		    bch_st & BIT(nfc->cfg->ecc1.err_flag_bit)) {
			mtd->ecc_stats.failed++;
			ecc_fail = 1;
		} else {
			cnt = ECC_ERR_CNT(bch_st, nfc->cfg->ecc0);
			mtd->ecc_stats.corrected += cnt;
			max_bitflips = max_t(u32, max_bitflips, cnt);

			cnt = ECC_ERR_CNT(bch_st, nfc->cfg->ecc1);
			mtd->ecc_stats.corrected += cnt;
			max_bitflips = max_t(u32, max_bitflips, cnt);
		}
	}

	if (buf)
		memcpy(buf, nfc->page_buf, mtd->writesize);

timeout_err:
	if (boot_rom_mode && rknand->boot_ecc != ecc->strength)
		rk_nfc_hw_ecc_setup(chip, ecc->strength);

	if (ret)
		return ret;

	if (ecc_fail) {
		dev_err(nfc->dev, "read page: %x ecc error!\n", page);
		return 0;
	}

	return max_bitflips;
}

static int rk_nfc_read_oob(struct nand_chip *chip, int page)
{
	return rk_nfc_read_page_hwecc(chip, NULL, 1, page);
}

static inline void rk_nfc_hw_init(struct rk_nfc *nfc)
{
	/* Disable flash wp. */
	writel(FMCTL_WP, nfc->regs + NFC_FMCTL);
	/* Config default timing 40ns at 150 Mhz NFC clock. */
	writel(0x1081, nfc->regs + NFC_FMWAIT);
	nfc->cur_timing = 0x1081;
	/* Disable randomizer and DMA. */
	writel(0, nfc->regs + nfc->cfg->randmz_off);
	writel(0, nfc->regs + nfc->cfg->dma_cfg_off);
	writel(FLCTL_RST, nfc->regs + nfc->cfg->flctl_off);
}

static irqreturn_t rk_nfc_irq(int irq, void *id)
{
	struct rk_nfc *nfc = id;
	u32 sta, ien;

	sta = readl_relaxed(nfc->regs + nfc->cfg->int_st_off);
	ien = readl_relaxed(nfc->regs + nfc->cfg->int_en_off);

	if (!(sta & ien))
		return IRQ_NONE;

	writel(sta, nfc->regs + nfc->cfg->int_clr_off);
	writel(~sta & ien, nfc->regs + nfc->cfg->int_en_off);

	complete(&nfc->done);

	return IRQ_HANDLED;
}

static int rk_nfc_enable_clks(struct device *dev, struct rk_nfc *nfc)
{
	int ret;

	if (!IS_ERR(nfc->nfc_clk)) {
		ret = clk_prepare_enable(nfc->nfc_clk);
		if (ret) {
			dev_err(dev, "failed to enable NFC clk\n");
			return ret;
		}
	}

	ret = clk_prepare_enable(nfc->ahb_clk);
	if (ret) {
		dev_err(dev, "failed to enable ahb clk\n");
		clk_disable_unprepare(nfc->nfc_clk);
		return ret;
	}

	return 0;
}

static void rk_nfc_disable_clks(struct rk_nfc *nfc)
{
	clk_disable_unprepare(nfc->nfc_clk);
	clk_disable_unprepare(nfc->ahb_clk);
}

static int rk_nfc_ooblayout_free(struct mtd_info *mtd, int section,
				 struct mtd_oob_region *oob_region)
{
	struct nand_chip *chip = mtd_to_nand(mtd);
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);

	if (section)
		return -ERANGE;

	/*
	 * The beginning of the OOB area stores the reserved data for the NFC,
	 * the size of the reserved data is NFC_SYS_DATA_SIZE bytes.
	 */
	oob_region->length = rknand->metadata_size - NFC_SYS_DATA_SIZE - 2;
	oob_region->offset = NFC_SYS_DATA_SIZE + 2;

	return 0;
}

static int rk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
				struct mtd_oob_region *oob_region)
{
	struct nand_chip *chip = mtd_to_nand(mtd);
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);

	if (section)
		return -ERANGE;

	oob_region->length = mtd->oobsize - rknand->metadata_size;
	oob_region->offset = rknand->metadata_size;

	return 0;
}

static const struct mtd_ooblayout_ops rk_nfc_ooblayout_ops = {
	.free = rk_nfc_ooblayout_free,
	.ecc = rk_nfc_ooblayout_ecc,
};

static int rk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd_to_nand(mtd);
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	const u8 *strengths = nfc->cfg->ecc_strengths;
	u8 max_strength, nfc_max_strength;
	int i;

	nfc_max_strength = nfc->cfg->ecc_strengths[0];
	/* If optional dt settings not present. */
	if (!ecc->size || !ecc->strength ||
	    ecc->strength > nfc_max_strength) {
		chip->ecc.size = 1024;
		ecc->steps = mtd->writesize / ecc->size;

		/*
		 * HW ECC always requests the number of ECC bytes per 1024 byte
		 * blocks. The first 4 OOB bytes are reserved for sys data.
		 */
		max_strength = ((mtd->oobsize / ecc->steps) - 4) * 8 /
				 fls(8 * 1024);
		if (max_strength > nfc_max_strength)
			max_strength = nfc_max_strength;

		for (i = 0; i < 4; i++) {
			if (max_strength >= strengths[i])
				break;
		}

		if (i >= 4) {
			dev_err(nfc->dev, "unsupported ECC strength\n");
			return -EOPNOTSUPP;
		}

		ecc->strength = strengths[i];
	}
	ecc->steps = mtd->writesize / ecc->size;
	ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * chip->ecc.size), 8);

	return 0;
}

static int rk_nfc_attach_chip(struct nand_chip *chip)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct device *dev = mtd->dev.parent;
	struct rk_nfc *nfc = nand_get_controller_data(chip);
	struct rk_nfc_nand_chip *rknand = rk_nfc_to_rknand(chip);
	struct nand_ecc_ctrl *ecc = &chip->ecc;
	int new_page_len, new_oob_len;
	void *buf;
	int ret;

	if (chip->options & NAND_BUSWIDTH_16) {
		dev_err(dev, "16 bits bus width not supported");
		return -EINVAL;
	}

	if (ecc->engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
		return 0;

	ret = rk_nfc_ecc_init(dev, mtd);
	if (ret)
		return ret;

	rknand->metadata_size = NFC_SYS_DATA_SIZE * ecc->steps;

	if (rknand->metadata_size < NFC_SYS_DATA_SIZE + 2) {
		dev_err(dev,
			"driver needs at least %d bytes of meta data\n",
			NFC_SYS_DATA_SIZE + 2);
		return -EIO;
	}

	/* Check buffer first, avoid duplicate alloc buffer. */
	new_page_len = mtd->writesize + mtd->oobsize;
	if (nfc->page_buf && new_page_len > nfc->page_buf_size) {
		buf = krealloc(nfc->page_buf, new_page_len,
			       GFP_KERNEL | GFP_DMA);
		if (!buf)
			return -ENOMEM;
		nfc->page_buf = buf;
		nfc->page_buf_size = new_page_len;
	}

	new_oob_len = ecc->steps * NFC_MAX_OOB_PER_STEP;
	if (nfc->oob_buf && new_oob_len > nfc->oob_buf_size) {
		buf = krealloc(nfc->oob_buf, new_oob_len,
			       GFP_KERNEL | GFP_DMA);
		if (!buf) {
			kfree(nfc->page_buf);
			nfc->page_buf = NULL;
			return -ENOMEM;
		}
		nfc->oob_buf = buf;
		nfc->oob_buf_size = new_oob_len;
	}

	if (!nfc->page_buf) {
		nfc->page_buf = kzalloc(new_page_len, GFP_KERNEL | GFP_DMA);
		if (!nfc->page_buf)
			return -ENOMEM;
		nfc->page_buf_size = new_page_len;
	}

	if (!nfc->oob_buf) {
		nfc->oob_buf = kzalloc(new_oob_len, GFP_KERNEL | GFP_DMA);
		if (!nfc->oob_buf) {
			kfree(nfc->page_buf);
			nfc->page_buf = NULL;
			return -ENOMEM;
		}
		nfc->oob_buf_size = new_oob_len;
	}

	chip->ecc.write_page_raw = rk_nfc_write_page_raw;
	chip->ecc.write_page = rk_nfc_write_page_hwecc;
	chip->ecc.write_oob = rk_nfc_write_oob;

	chip->ecc.read_page_raw = rk_nfc_read_page_raw;
	chip->ecc.read_page = rk_nfc_read_page_hwecc;
	chip->ecc.read_oob = rk_nfc_read_oob;

	return 0;
}

static const struct nand_controller_ops rk_nfc_controller_ops = {
	.attach_chip = rk_nfc_attach_chip,
	.exec_op = rk_nfc_exec_op,
	.setup_interface = rk_nfc_setup_interface,
};

static int rk_nfc_nand_chip_init(struct device *dev, struct rk_nfc *nfc,
				 struct device_node *np)
{
	struct rk_nfc_nand_chip *rknand;
	struct nand_chip *chip;
	struct mtd_info *mtd;
	int nsels;
	u32 tmp;
	int ret;
	int i;

	if (!of_get_property(np, "reg", &nsels))
		return -ENODEV;
	nsels /= sizeof(u32);
	if (!nsels || nsels > NFC_MAX_NSELS) {
		dev_err(dev, "invalid reg property size %d\n", nsels);
		return -EINVAL;
	}

	rknand = devm_kzalloc(dev, sizeof(*rknand) + nsels * sizeof(u8),
			      GFP_KERNEL);
	if (!rknand)
		return -ENOMEM;

	rknand->nsels = nsels;
	for (i = 0; i < nsels; i++) {
		ret = of_property_read_u32_index(np, "reg", i, &tmp);
		if (ret) {
			dev_err(dev, "reg property failure : %d\n", ret);
			return ret;
		}

		if (tmp >= NFC_MAX_NSELS) {
			dev_err(dev, "invalid CS: %u\n", tmp);
			return -EINVAL;
		}

		if (test_and_set_bit(tmp, &nfc->assigned_cs)) {
			dev_err(dev, "CS %u already assigned\n", tmp);
			return -EINVAL;
		}

		rknand->sels[i] = tmp;
	}

	chip = &rknand->chip;
	chip->controller = &nfc->controller;

	nand_set_flash_node(chip, np);

	nand_set_controller_data(chip, nfc);

	chip->options |= NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE;
	chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;

	/* Set default mode in case dt entry is missing. */
	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;

	mtd = nand_to_mtd(chip);
	mtd->owner = THIS_MODULE;
	mtd->dev.parent = dev;

	if (!mtd->name) {
		dev_err(nfc->dev, "NAND label property is mandatory\n");
		return -EINVAL;
	}

	mtd_set_ooblayout(mtd, &rk_nfc_ooblayout_ops);
	rk_nfc_hw_init(nfc);
	ret = nand_scan(chip, nsels);
	if (ret)
		return ret;

	if (chip->options & NAND_IS_BOOT_MEDIUM) {
		ret = of_property_read_u32(np, "rockchip,boot-blks", &tmp);
		rknand->boot_blks = ret ? 0 : tmp;

		ret = of_property_read_u32(np, "rockchip,boot-ecc-strength",
					   &tmp);
		rknand->boot_ecc = ret ? chip->ecc.strength : tmp;
	}

	ret = mtd_device_register(mtd, NULL, 0);
	if (ret) {
		dev_err(dev, "MTD parse partition error\n");
		nand_cleanup(chip);
		return ret;
	}

	list_add_tail(&rknand->node, &nfc->chips);

	return 0;
}

static void rk_nfc_chips_cleanup(struct rk_nfc *nfc)
{
	struct rk_nfc_nand_chip *rknand, *tmp;
	struct nand_chip *chip;
	int ret;

	list_for_each_entry_safe(rknand, tmp, &nfc->chips, node) {
		chip = &rknand->chip;
		ret = mtd_device_unregister(nand_to_mtd(chip));
		WARN_ON(ret);
		nand_cleanup(chip);
		list_del(&rknand->node);
	}
}

static int rk_nfc_nand_chips_init(struct device *dev, struct rk_nfc *nfc)
{
	struct device_node *np = dev->of_node, *nand_np;
	int nchips = of_get_child_count(np);
	int ret;

	if (!nchips || nchips > NFC_MAX_NSELS) {
		dev_err(nfc->dev, "incorrect number of NAND chips (%d)\n",
			nchips);
		return -EINVAL;
	}

	for_each_child_of_node(np, nand_np) {
		ret = rk_nfc_nand_chip_init(dev, nfc, nand_np);
		if (ret) {
			of_node_put(nand_np);
			rk_nfc_chips_cleanup(nfc);
			return ret;
		}
	}

	return 0;
}

static struct nfc_cfg nfc_v6_cfg = {
		.type			= NFC_V6,
		.ecc_strengths		= {60, 40, 24, 16},
		.ecc_cfgs		= {
			0x00040011, 0x00040001, 0x00000011, 0x00000001,
		},
		.flctl_off		= 0x08,
		.bchctl_off		= 0x0C,
		.dma_cfg_off		= 0x10,
		.dma_data_buf_off	= 0x14,
		.dma_oob_buf_off	= 0x18,
		.dma_st_off		= 0x1C,
		.bch_st_off		= 0x20,
		.randmz_off		= 0x150,
		.int_en_off		= 0x16C,
		.int_clr_off		= 0x170,
		.int_st_off		= 0x174,
		.oob0_off		= 0x200,
		.oob1_off		= 0x230,
		.ecc0			= {
			.err_flag_bit	= 2,
			.low		= 3,
			.low_mask	= 0x1F,
			.low_bn		= 5,
			.high		= 27,
			.high_mask	= 0x1,
		},
		.ecc1			= {
			.err_flag_bit	= 15,
			.low		= 16,
			.low_mask	= 0x1F,
			.low_bn		= 5,
			.high		= 29,
			.high_mask	= 0x1,
		},
};

static struct nfc_cfg nfc_v8_cfg = {
		.type			= NFC_V8,
		.ecc_strengths		= {16, 16, 16, 16},
		.ecc_cfgs		= {
			0x00000001, 0x00000001, 0x00000001, 0x00000001,
		},
		.flctl_off		= 0x08,
		.bchctl_off		= 0x0C,
		.dma_cfg_off		= 0x10,
		.dma_data_buf_off	= 0x14,
		.dma_oob_buf_off	= 0x18,
		.dma_st_off		= 0x1C,
		.bch_st_off		= 0x20,
		.randmz_off		= 0x150,
		.int_en_off		= 0x16C,
		.int_clr_off		= 0x170,
		.int_st_off		= 0x174,
		.oob0_off		= 0x200,
		.oob1_off		= 0x230,
		.ecc0			= {
			.err_flag_bit	= 2,
			.low		= 3,
			.low_mask	= 0x1F,
			.low_bn		= 5,
			.high		= 27,
			.high_mask	= 0x1,
		},
		.ecc1			= {
			.err_flag_bit	= 15,
			.low		= 16,
			.low_mask	= 0x1F,
			.low_bn		= 5,
			.high		= 29,
			.high_mask	= 0x1,
		},
};

static struct nfc_cfg nfc_v9_cfg = {
		.type			= NFC_V9,
		.ecc_strengths		= {70, 60, 40, 16},
		.ecc_cfgs		= {
			0x00000001, 0x06000001, 0x04000001, 0x02000001,
		},
		.flctl_off		= 0x10,
		.bchctl_off		= 0x20,
		.dma_cfg_off		= 0x30,
		.dma_data_buf_off	= 0x34,
		.dma_oob_buf_off	= 0x38,
		.dma_st_off		= 0x3C,
		.bch_st_off		= 0x150,
		.randmz_off		= 0x208,
		.int_en_off		= 0x120,
		.int_clr_off		= 0x124,
		.int_st_off		= 0x128,
		.oob0_off		= 0x200,
		.oob1_off		= 0x204,
		.ecc0			= {
			.err_flag_bit	= 2,
			.low		= 3,
			.low_mask	= 0x7F,
			.low_bn		= 7,
			.high		= 0,
			.high_mask	= 0x0,
		},
		.ecc1			= {
			.err_flag_bit	= 18,
			.low		= 19,
			.low_mask	= 0x7F,
			.low_bn		= 7,
			.high		= 0,
			.high_mask	= 0x0,
		},
};

static const struct of_device_id rk_nfc_id_table[] = {
	{
		.compatible = "rockchip,px30-nfc",
		.data = &nfc_v9_cfg
	},
	{
		.compatible = "rockchip,rk2928-nfc",
		.data = &nfc_v6_cfg
	},
	{
		.compatible = "rockchip,rv1108-nfc",
		.data = &nfc_v8_cfg
	},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rk_nfc_id_table);

static int rk_nfc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rk_nfc *nfc;
	int ret, irq;

	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
	if (!nfc)
		return -ENOMEM;

	nand_controller_init(&nfc->controller);
	INIT_LIST_HEAD(&nfc->chips);
	nfc->controller.ops = &rk_nfc_controller_ops;

	nfc->cfg = of_device_get_match_data(dev);
	nfc->dev = dev;

	init_completion(&nfc->done);

	nfc->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(nfc->regs)) {
		ret = PTR_ERR(nfc->regs);
		goto release_nfc;
	}

	nfc->nfc_clk = devm_clk_get(dev, "nfc");
	if (IS_ERR(nfc->nfc_clk)) {
		dev_dbg(dev, "no NFC clk\n");
		/* Some earlier models, such as rk3066, have no NFC clk. */
	}

	nfc->ahb_clk = devm_clk_get(dev, "ahb");
	if (IS_ERR(nfc->ahb_clk)) {
		dev_err(dev, "no ahb clk\n");
		ret = PTR_ERR(nfc->ahb_clk);
		goto release_nfc;
	}

	ret = rk_nfc_enable_clks(dev, nfc);
	if (ret)
		goto release_nfc;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = -EINVAL;
		goto clk_disable;
	}

	writel(0, nfc->regs + nfc->cfg->int_en_off);
	ret = devm_request_irq(dev, irq, rk_nfc_irq, 0x0, "rk-nand", nfc);
	if (ret) {
		dev_err(dev, "failed to request NFC irq\n");
		goto clk_disable;
	}

	platform_set_drvdata(pdev, nfc);

	ret = rk_nfc_nand_chips_init(dev, nfc);
	if (ret) {
		dev_err(dev, "failed to init NAND chips\n");
		goto clk_disable;
	}
	return 0;

clk_disable:
	rk_nfc_disable_clks(nfc);
release_nfc:
	return ret;
}

static int rk_nfc_remove(struct platform_device *pdev)
{
	struct rk_nfc *nfc = platform_get_drvdata(pdev);

	kfree(nfc->page_buf);
	kfree(nfc->oob_buf);
	rk_nfc_chips_cleanup(nfc);
	rk_nfc_disable_clks(nfc);

	return 0;
}

static int __maybe_unused rk_nfc_suspend(struct device *dev)
{
	struct rk_nfc *nfc = dev_get_drvdata(dev);

	rk_nfc_disable_clks(nfc);

	return 0;
}

static int __maybe_unused rk_nfc_resume(struct device *dev)
{
	struct rk_nfc *nfc = dev_get_drvdata(dev);
	struct rk_nfc_nand_chip *rknand;
	struct nand_chip *chip;
	int ret;
	u32 i;

	ret = rk_nfc_enable_clks(dev, nfc);
	if (ret)
		return ret;

	/* Reset NAND chip if VCC was powered off. */
	list_for_each_entry(rknand, &nfc->chips, node) {
		chip = &rknand->chip;
		for (i = 0; i < rknand->nsels; i++)
			nand_reset(chip, i);
	}

	return 0;
}

static const struct dev_pm_ops rk_nfc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(rk_nfc_suspend, rk_nfc_resume)
};

static struct platform_driver rk_nfc_driver = {
	.probe = rk_nfc_probe,
	.remove = rk_nfc_remove,
	.driver = {
		.name = "rockchip-nfc",
		.of_match_table = rk_nfc_id_table,
		.pm = &rk_nfc_pm_ops,
	},
};

module_platform_driver(rk_nfc_driver);

MODULE_LICENSE("Dual MIT/GPL");
MODULE_AUTHOR("Yifeng Zhao <yifeng.zhao@rock-chips.com>");
MODULE_DESCRIPTION("Rockchip Nand Flash Controller Driver");
MODULE_ALIAS("platform:rockchip-nand-controller");
