// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2020 Intel Corporation. */

#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/dmaengine.h>
#include <linux/dma-direction.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand.h>

#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/units.h>
#include <asm/unaligned.h>

#define EBU_CLC			0x000
#define EBU_CLC_RST		0x00000000u

#define EBU_ADDR_SEL(n)		(0x020 + (n) * 4)
/* 5 bits 26:22 included for comparison in the ADDR_SELx */
#define EBU_ADDR_MASK(x)	((x) << 4)
#define EBU_ADDR_SEL_REGEN	0x1

#define EBU_BUSCON(n)		(0x060 + (n) * 4)
#define EBU_BUSCON_CMULT_V4	0x1
#define EBU_BUSCON_RECOVC(n)	((n) << 2)
#define EBU_BUSCON_HOLDC(n)	((n) << 4)
#define EBU_BUSCON_WAITRDC(n)	((n) << 6)
#define EBU_BUSCON_WAITWRC(n)	((n) << 8)
#define EBU_BUSCON_BCGEN_CS	0x0
#define EBU_BUSCON_SETUP_EN	BIT(22)
#define EBU_BUSCON_ALEC		0xC000

#define EBU_CON			0x0B0
#define EBU_CON_NANDM_EN	BIT(0)
#define EBU_CON_NANDM_DIS	0x0
#define EBU_CON_CSMUX_E_EN	BIT(1)
#define EBU_CON_ALE_P_LOW	BIT(2)
#define EBU_CON_CLE_P_LOW	BIT(3)
#define EBU_CON_CS_P_LOW	BIT(4)
#define EBU_CON_SE_P_LOW	BIT(5)
#define EBU_CON_WP_P_LOW	BIT(6)
#define EBU_CON_PRE_P_LOW	BIT(7)
#define EBU_CON_IN_CS_S(n)	((n) << 8)
#define EBU_CON_OUT_CS_S(n)	((n) << 10)
#define EBU_CON_LAT_EN_CS_P	((0x3D) << 18)

#define EBU_WAIT		0x0B4
#define EBU_WAIT_RDBY		BIT(0)
#define EBU_WAIT_WR_C		BIT(3)

#define HSNAND_CTL1		0x110
#define HSNAND_CTL1_ADDR_SHIFT	24

#define HSNAND_CTL2		0x114
#define HSNAND_CTL2_ADDR_SHIFT	8
#define HSNAND_CTL2_CYC_N_V5	(0x2 << 16)

#define HSNAND_INT_MSK_CTL	0x124
#define HSNAND_INT_MSK_CTL_WR_C	BIT(4)

#define HSNAND_INT_STA		0x128
#define HSNAND_INT_STA_WR_C	BIT(4)

#define HSNAND_CTL		0x130
#define HSNAND_CTL_ENABLE_ECC	BIT(0)
#define HSNAND_CTL_GO		BIT(2)
#define HSNAND_CTL_CE_SEL_CS(n)	BIT(3 + (n))
#define HSNAND_CTL_RW_READ	0x0
#define HSNAND_CTL_RW_WRITE	BIT(10)
#define HSNAND_CTL_ECC_OFF_V8TH	BIT(11)
#define HSNAND_CTL_CKFF_EN	0x0
#define HSNAND_CTL_MSG_EN	BIT(17)

#define HSNAND_PARA0		0x13c
#define HSNAND_PARA0_PAGE_V8192	0x3
#define HSNAND_PARA0_PIB_V256	(0x3 << 4)
#define HSNAND_PARA0_BYP_EN_NP	0x0
#define HSNAND_PARA0_BYP_DEC_NP	0x0
#define HSNAND_PARA0_TYPE_ONFI	BIT(18)
#define HSNAND_PARA0_ADEP_EN	BIT(21)

#define HSNAND_CMSG_0		0x150
#define HSNAND_CMSG_1		0x154

#define HSNAND_ALE_OFFS		BIT(2)
#define HSNAND_CLE_OFFS		BIT(3)
#define HSNAND_CS_OFFS		BIT(4)

#define HSNAND_ECC_OFFSET	0x008

#define MAX_CS	2

#define USEC_PER_SEC	1000000L

struct ebu_nand_cs {
	void __iomem *chipaddr;
	u32 addr_sel;
};

struct ebu_nand_controller {
	struct nand_controller controller;
	struct nand_chip chip;
	struct device *dev;
	void __iomem *ebu;
	void __iomem *hsnand;
	struct dma_chan *dma_tx;
	struct dma_chan *dma_rx;
	struct completion dma_access_complete;
	struct clk *clk;
	u32 nd_para0;
	u8 cs_num;
	struct ebu_nand_cs cs[MAX_CS];
};

static inline struct ebu_nand_controller *nand_to_ebu(struct nand_chip *chip)
{
	return container_of(chip, struct ebu_nand_controller, chip);
}

static int ebu_nand_waitrdy(struct nand_chip *chip, int timeout_ms)
{
	struct ebu_nand_controller *ctrl = nand_to_ebu(chip);
	u32 status;

	return readl_poll_timeout(ctrl->ebu + EBU_WAIT, status,
				  (status & EBU_WAIT_RDBY) ||
				  (status & EBU_WAIT_WR_C), 20, timeout_ms);
}

static u8 ebu_nand_readb(struct nand_chip *chip)
{
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);
	u8 cs_num = ebu_host->cs_num;
	u8 val;

	val = readb(ebu_host->cs[cs_num].chipaddr + HSNAND_CS_OFFS);
	ebu_nand_waitrdy(chip, 1000);
	return val;
}

static void ebu_nand_writeb(struct nand_chip *chip, u32 offset, u8 value)
{
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);
	u8 cs_num = ebu_host->cs_num;

	writeb(value, ebu_host->cs[cs_num].chipaddr + offset);
	ebu_nand_waitrdy(chip, 1000);
}

static void ebu_read_buf(struct nand_chip *chip, u_char *buf, unsigned int len)
{
	int i;

	for (i = 0; i < len; i++)
		buf[i] = ebu_nand_readb(chip);
}

static void ebu_write_buf(struct nand_chip *chip, const u_char *buf, int len)
{
	int i;

	for (i = 0; i < len; i++)
		ebu_nand_writeb(chip, HSNAND_CS_OFFS, buf[i]);
}

static void ebu_nand_disable(struct nand_chip *chip)
{
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);

	writel(0, ebu_host->ebu + EBU_CON);
}

static void ebu_select_chip(struct nand_chip *chip)
{
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);
	void __iomem *nand_con = ebu_host->ebu + EBU_CON;
	u32 cs = ebu_host->cs_num;

	writel(EBU_CON_NANDM_EN | EBU_CON_CSMUX_E_EN | EBU_CON_CS_P_LOW |
	       EBU_CON_SE_P_LOW | EBU_CON_WP_P_LOW | EBU_CON_PRE_P_LOW |
	       EBU_CON_IN_CS_S(cs) | EBU_CON_OUT_CS_S(cs) |
	       EBU_CON_LAT_EN_CS_P, nand_con);
}

static int ebu_nand_set_timings(struct nand_chip *chip, int csline,
				const struct nand_interface_config *conf)
{
	struct ebu_nand_controller *ctrl = nand_to_ebu(chip);
	unsigned int rate = clk_get_rate(ctrl->clk) / HZ_PER_MHZ;
	unsigned int period = DIV_ROUND_UP(USEC_PER_SEC, rate);
	const struct nand_sdr_timings *timings;
	u32 trecov, thold, twrwait, trdwait;
	u32 reg = 0;

	timings = nand_get_sdr_timings(conf);
	if (IS_ERR(timings))
		return PTR_ERR(timings);

	if (csline == NAND_DATA_IFACE_CHECK_ONLY)
		return 0;

	trecov = DIV_ROUND_UP(max(timings->tREA_max, timings->tREH_min),
			      period);
	reg |= EBU_BUSCON_RECOVC(trecov);

	thold = DIV_ROUND_UP(max(timings->tDH_min, timings->tDS_min), period);
	reg |= EBU_BUSCON_HOLDC(thold);

	trdwait = DIV_ROUND_UP(max(timings->tRC_min, timings->tREH_min),
			       period);
	reg |= EBU_BUSCON_WAITRDC(trdwait);

	twrwait = DIV_ROUND_UP(max(timings->tWC_min, timings->tWH_min), period);
	reg |= EBU_BUSCON_WAITWRC(twrwait);

	reg |= EBU_BUSCON_CMULT_V4 | EBU_BUSCON_BCGEN_CS | EBU_BUSCON_ALEC |
		EBU_BUSCON_SETUP_EN;

	writel(reg, ctrl->ebu + EBU_BUSCON(ctrl->cs_num));

	return 0;
}

static int ebu_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
				  struct mtd_oob_region *oobregion)
{
	struct nand_chip *chip = mtd_to_nand(mtd);

	if (section)
		return -ERANGE;

	oobregion->offset = HSNAND_ECC_OFFSET;
	oobregion->length = chip->ecc.total;

	return 0;
}

static int ebu_nand_ooblayout_free(struct mtd_info *mtd, int section,
				   struct mtd_oob_region *oobregion)
{
	struct nand_chip *chip = mtd_to_nand(mtd);

	if (section)
		return -ERANGE;

	oobregion->offset = chip->ecc.total + HSNAND_ECC_OFFSET;
	oobregion->length = mtd->oobsize - oobregion->offset;

	return 0;
}

static const struct mtd_ooblayout_ops ebu_nand_ooblayout_ops = {
	.ecc = ebu_nand_ooblayout_ecc,
	.free = ebu_nand_ooblayout_free,
};

static void ebu_dma_rx_callback(void *cookie)
{
	struct ebu_nand_controller *ebu_host = cookie;

	dmaengine_terminate_async(ebu_host->dma_rx);

	complete(&ebu_host->dma_access_complete);
}

static void ebu_dma_tx_callback(void *cookie)
{
	struct ebu_nand_controller *ebu_host = cookie;

	dmaengine_terminate_async(ebu_host->dma_tx);

	complete(&ebu_host->dma_access_complete);
}

static int ebu_dma_start(struct ebu_nand_controller *ebu_host, u32 dir,
			 const u8 *buf, u32 len)
{
	struct dma_async_tx_descriptor *tx;
	struct completion *dma_completion;
	dma_async_tx_callback callback;
	struct dma_chan *chan;
	dma_cookie_t cookie;
	unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
	dma_addr_t buf_dma;
	int ret;
	u32 timeout;

	if (dir == DMA_DEV_TO_MEM) {
		chan = ebu_host->dma_rx;
		dma_completion = &ebu_host->dma_access_complete;
		callback = ebu_dma_rx_callback;
	} else {
		chan = ebu_host->dma_tx;
		dma_completion = &ebu_host->dma_access_complete;
		callback = ebu_dma_tx_callback;
	}

	buf_dma = dma_map_single(chan->device->dev, (void *)buf, len, dir);
	if (dma_mapping_error(chan->device->dev, buf_dma)) {
		dev_err(ebu_host->dev, "Failed to map DMA buffer\n");
		ret = -EIO;
		goto err_unmap;
	}

	tx = dmaengine_prep_slave_single(chan, buf_dma, len, dir, flags);
	if (!tx) {
		ret = -ENXIO;
		goto err_unmap;
	}

	tx->callback = callback;
	tx->callback_param = ebu_host;
	cookie = tx->tx_submit(tx);

	ret = dma_submit_error(cookie);
	if (ret) {
		dev_err(ebu_host->dev, "dma_submit_error %d\n", cookie);
		ret = -EIO;
		goto err_unmap;
	}

	init_completion(dma_completion);
	dma_async_issue_pending(chan);

	/* Wait DMA to finish the data transfer.*/
	timeout = wait_for_completion_timeout(dma_completion, msecs_to_jiffies(1000));
	if (!timeout) {
		dev_err(ebu_host->dev, "I/O Error in DMA RX (status %d)\n",
			dmaengine_tx_status(chan, cookie, NULL));
		dmaengine_terminate_sync(chan);
		ret = -ETIMEDOUT;
		goto err_unmap;
	}

	return 0;

err_unmap:
	dma_unmap_single(ebu_host->dev, buf_dma, len, dir);

	return ret;
}

static void ebu_nand_trigger(struct ebu_nand_controller *ebu_host,
			     int page, u32 cmd)
{
	unsigned int val;

	val = cmd | (page & 0xFF) << HSNAND_CTL1_ADDR_SHIFT;
	writel(val, ebu_host->hsnand + HSNAND_CTL1);
	val = (page & 0xFFFF00) >> 8 | HSNAND_CTL2_CYC_N_V5;
	writel(val, ebu_host->hsnand + HSNAND_CTL2);

	writel(ebu_host->nd_para0, ebu_host->hsnand + HSNAND_PARA0);

	/* clear first, will update later */
	writel(0xFFFFFFFF, ebu_host->hsnand + HSNAND_CMSG_0);
	writel(0xFFFFFFFF, ebu_host->hsnand + HSNAND_CMSG_1);

	writel(HSNAND_INT_MSK_CTL_WR_C,
	       ebu_host->hsnand + HSNAND_INT_MSK_CTL);

	if (!cmd)
		val = HSNAND_CTL_RW_READ;
	else
		val = HSNAND_CTL_RW_WRITE;

	writel(HSNAND_CTL_MSG_EN | HSNAND_CTL_CKFF_EN |
	       HSNAND_CTL_ECC_OFF_V8TH | HSNAND_CTL_CE_SEL_CS(ebu_host->cs_num) |
	       HSNAND_CTL_ENABLE_ECC | HSNAND_CTL_GO | val,
	       ebu_host->hsnand + HSNAND_CTL);
}

static int ebu_nand_read_page_hwecc(struct nand_chip *chip, u8 *buf,
				    int oob_required, int page)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);
	int ret, reg_data;

	ebu_nand_trigger(ebu_host, page, NAND_CMD_READ0);

	ret = ebu_dma_start(ebu_host, DMA_DEV_TO_MEM, buf, mtd->writesize);
	if (ret)
		return ret;

	if (oob_required)
		chip->ecc.read_oob(chip, page);

	reg_data = readl(ebu_host->hsnand + HSNAND_CTL);
	reg_data &= ~HSNAND_CTL_GO;
	writel(reg_data, ebu_host->hsnand + HSNAND_CTL);

	return 0;
}

static int ebu_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf,
				     int oob_required, int page)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);
	void __iomem *int_sta = ebu_host->hsnand + HSNAND_INT_STA;
	int reg_data, ret, val;
	u32 reg;

	ebu_nand_trigger(ebu_host, page, NAND_CMD_SEQIN);

	ret = ebu_dma_start(ebu_host, DMA_MEM_TO_DEV, buf, mtd->writesize);
	if (ret)
		return ret;

	if (oob_required) {
		reg = get_unaligned_le32(chip->oob_poi);
		writel(reg, ebu_host->hsnand + HSNAND_CMSG_0);

		reg = get_unaligned_le32(chip->oob_poi + 4);
		writel(reg, ebu_host->hsnand + HSNAND_CMSG_1);
	}

	ret = readl_poll_timeout_atomic(int_sta, val, !(val & HSNAND_INT_STA_WR_C),
					10, 1000);
	if (ret)
		return ret;

	reg_data = readl(ebu_host->hsnand + HSNAND_CTL);
	reg_data &= ~HSNAND_CTL_GO;
	writel(reg_data, ebu_host->hsnand + HSNAND_CTL);

	return 0;
}

static const u8 ecc_strength[] = { 1, 1, 4, 8, 24, 32, 40, 60, };

static int ebu_nand_attach_chip(struct nand_chip *chip)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip);
	u32 ecc_steps, ecc_bytes, ecc_total, pagesize, pg_per_blk;
	u32 ecc_strength_ds = chip->ecc.strength;
	u32 ecc_size = chip->ecc.size;
	u32 writesize = mtd->writesize;
	u32 blocksize = mtd->erasesize;
	int bch_algo, start, val;

	/* Default to an ECC size of 512 */
	if (!chip->ecc.size)
		chip->ecc.size = 512;

	switch (ecc_size) {
	case 512:
		start = 1;
		if (!ecc_strength_ds)
			ecc_strength_ds = 4;
		break;
	case 1024:
		start = 4;
		if (!ecc_strength_ds)
			ecc_strength_ds = 32;
		break;
	default:
		return -EINVAL;
	}

	/* BCH ECC algorithm Settings for number of bits per 512B/1024B */
	bch_algo = round_up(start + 1, 4);
	for (val = start; val < bch_algo; val++) {
		if (ecc_strength_ds == ecc_strength[val])
			break;
	}
	if (val == bch_algo)
		return -EINVAL;

	if (ecc_strength_ds == 8)
		ecc_bytes = 14;
	else
		ecc_bytes = DIV_ROUND_UP(ecc_strength_ds * fls(8 * ecc_size), 8);

	ecc_steps = writesize / ecc_size;
	ecc_total = ecc_steps * ecc_bytes;
	if ((ecc_total + 8) > mtd->oobsize)
		return -ERANGE;

	chip->ecc.total = ecc_total;
	pagesize = fls(writesize >> 11);
	if (pagesize > HSNAND_PARA0_PAGE_V8192)
		return -ERANGE;

	pg_per_blk = fls((blocksize / writesize) >> 6) / 8;
	if (pg_per_blk > HSNAND_PARA0_PIB_V256)
		return -ERANGE;

	ebu_host->nd_para0 = pagesize | pg_per_blk | HSNAND_PARA0_BYP_EN_NP |
			     HSNAND_PARA0_BYP_DEC_NP | HSNAND_PARA0_ADEP_EN |
			     HSNAND_PARA0_TYPE_ONFI | (val << 29);

	mtd_set_ooblayout(mtd, &ebu_nand_ooblayout_ops);
	chip->ecc.read_page = ebu_nand_read_page_hwecc;
	chip->ecc.write_page = ebu_nand_write_page_hwecc;

	return 0;
}

static int ebu_nand_exec_op(struct nand_chip *chip,
			    const struct nand_operation *op, bool check_only)
{
	const struct nand_op_instr *instr = NULL;
	unsigned int op_id;
	int i, timeout_ms, ret = 0;

	if (check_only)
		return 0;

	ebu_select_chip(chip);
	for (op_id = 0; op_id < op->ninstrs; op_id++) {
		instr = &op->instrs[op_id];

		switch (instr->type) {
		case NAND_OP_CMD_INSTR:
			ebu_nand_writeb(chip, HSNAND_CLE_OFFS | HSNAND_CS_OFFS,
					instr->ctx.cmd.opcode);
			break;

		case NAND_OP_ADDR_INSTR:
			for (i = 0; i < instr->ctx.addr.naddrs; i++)
				ebu_nand_writeb(chip,
						HSNAND_ALE_OFFS | HSNAND_CS_OFFS,
						instr->ctx.addr.addrs[i]);
			break;

		case NAND_OP_DATA_IN_INSTR:
			ebu_read_buf(chip, instr->ctx.data.buf.in,
				     instr->ctx.data.len);
			break;

		case NAND_OP_DATA_OUT_INSTR:
			ebu_write_buf(chip, instr->ctx.data.buf.out,
				      instr->ctx.data.len);
			break;

		case NAND_OP_WAITRDY_INSTR:
			timeout_ms = instr->ctx.waitrdy.timeout_ms * 1000;
			ret = ebu_nand_waitrdy(chip, timeout_ms);
			break;
		}
	}

	return ret;
}

static const struct nand_controller_ops ebu_nand_controller_ops = {
	.attach_chip = ebu_nand_attach_chip,
	.setup_interface = ebu_nand_set_timings,
	.exec_op = ebu_nand_exec_op,
};

static void ebu_dma_cleanup(struct ebu_nand_controller *ebu_host)
{
	if (ebu_host->dma_rx)
		dma_release_channel(ebu_host->dma_rx);

	if (ebu_host->dma_tx)
		dma_release_channel(ebu_host->dma_tx);
}

static int ebu_nand_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ebu_nand_controller *ebu_host;
	struct device_node *chip_np;
	struct nand_chip *nand;
	struct mtd_info *mtd;
	struct resource *res;
	char *resname;
	int ret;
	u32 cs;

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

	ebu_host->dev = dev;
	nand_controller_init(&ebu_host->controller);

	ebu_host->ebu = devm_platform_ioremap_resource_byname(pdev, "ebunand");
	if (IS_ERR(ebu_host->ebu))
		return PTR_ERR(ebu_host->ebu);

	ebu_host->hsnand = devm_platform_ioremap_resource_byname(pdev, "hsnand");
	if (IS_ERR(ebu_host->hsnand))
		return PTR_ERR(ebu_host->hsnand);

	chip_np = of_get_next_child(dev->of_node, NULL);
	if (!chip_np)
		return dev_err_probe(dev, -EINVAL,
				     "Could not find child node for the NAND chip\n");

	ret = of_property_read_u32(chip_np, "reg", &cs);
	if (ret) {
		dev_err(dev, "failed to get chip select: %d\n", ret);
		goto err_of_node_put;
	}
	if (cs >= MAX_CS) {
		dev_err(dev, "got invalid chip select: %d\n", cs);
		ret = -EINVAL;
		goto err_of_node_put;
	}

	ebu_host->cs_num = cs;

	resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
	ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
									  resname);
	if (IS_ERR(ebu_host->cs[cs].chipaddr)) {
		ret = PTR_ERR(ebu_host->cs[cs].chipaddr);
		goto err_of_node_put;
	}

	ebu_host->clk = devm_clk_get_enabled(dev, NULL);
	if (IS_ERR(ebu_host->clk)) {
		ret = dev_err_probe(dev, PTR_ERR(ebu_host->clk),
				    "failed to get and enable clock\n");
		goto err_of_node_put;
	}

	ebu_host->dma_tx = dma_request_chan(dev, "tx");
	if (IS_ERR(ebu_host->dma_tx)) {
		ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx),
				    "failed to request DMA tx chan!.\n");
		goto err_of_node_put;
	}

	ebu_host->dma_rx = dma_request_chan(dev, "rx");
	if (IS_ERR(ebu_host->dma_rx)) {
		ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx),
				    "failed to request DMA rx chan!.\n");
		ebu_host->dma_rx = NULL;
		goto err_cleanup_dma;
	}

	resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs);
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
	if (!res) {
		ret = -EINVAL;
		goto err_cleanup_dma;
	}
	ebu_host->cs[cs].addr_sel = res->start;
	writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
	       ebu_host->ebu + EBU_ADDR_SEL(cs));

	nand_set_flash_node(&ebu_host->chip, chip_np);

	mtd = nand_to_mtd(&ebu_host->chip);
	if (!mtd->name) {
		dev_err(ebu_host->dev, "NAND label property is mandatory\n");
		ret = -EINVAL;
		goto err_cleanup_dma;
	}

	mtd->dev.parent = dev;
	ebu_host->dev = dev;

	platform_set_drvdata(pdev, ebu_host);
	nand_set_controller_data(&ebu_host->chip, ebu_host);

	nand = &ebu_host->chip;
	nand->controller = &ebu_host->controller;
	nand->controller->ops = &ebu_nand_controller_ops;

	/* Scan to find existence of the device */
	ret = nand_scan(&ebu_host->chip, 1);
	if (ret)
		goto err_cleanup_dma;

	ret = mtd_device_register(mtd, NULL, 0);
	if (ret)
		goto err_clean_nand;

	return 0;

err_clean_nand:
	nand_cleanup(&ebu_host->chip);
err_cleanup_dma:
	ebu_dma_cleanup(ebu_host);
err_of_node_put:
	of_node_put(chip_np);

	return ret;
}

static void ebu_nand_remove(struct platform_device *pdev)
{
	struct ebu_nand_controller *ebu_host = platform_get_drvdata(pdev);
	int ret;

	ret = mtd_device_unregister(nand_to_mtd(&ebu_host->chip));
	WARN_ON(ret);
	nand_cleanup(&ebu_host->chip);
	ebu_nand_disable(&ebu_host->chip);
	ebu_dma_cleanup(ebu_host);
}

static const struct of_device_id ebu_nand_match[] = {
	{ .compatible = "intel,lgm-ebunand" },
	{}
};
MODULE_DEVICE_TABLE(of, ebu_nand_match);

static struct platform_driver ebu_nand_driver = {
	.probe = ebu_nand_probe,
	.remove_new = ebu_nand_remove,
	.driver = {
		.name = "intel-nand-controller",
		.of_match_table = ebu_nand_match,
	},

};
module_platform_driver(ebu_nand_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Vadivel Murugan R <vadivel.muruganx.ramuthevar@intel.com>");
MODULE_DESCRIPTION("Intel's LGM External Bus NAND Controller driver");
