/*
 * Freescale GPMI NAND Flash Driver
 *
 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
 * Copyright (C) 2008 Embedded Alley Solutions, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mtd/gpmi-nand.h>
#include <linux/mtd/partitions.h>
#include <linux/pinctrl/consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include "gpmi-nand.h"

/* add our owner bbt descriptor */
static uint8_t scan_ff_pattern[] = { 0xff };
static struct nand_bbt_descr gpmi_bbt_descr = {
	.options	= 0,
	.offs		= 0,
	.len		= 1,
	.pattern	= scan_ff_pattern
};

/*  We will use all the (page + OOB). */
static struct nand_ecclayout gpmi_hw_ecclayout = {
	.eccbytes = 0,
	.eccpos = { 0, },
	.oobfree = { {.offset = 0, .length = 0} }
};

static irqreturn_t bch_irq(int irq, void *cookie)
{
	struct gpmi_nand_data *this = cookie;

	gpmi_clear_bch(this);
	complete(&this->bch_done);
	return IRQ_HANDLED;
}

/*
 *  Calculate the ECC strength by hand:
 *	E : The ECC strength.
 *	G : the length of Galois Field.
 *	N : The chunk count of per page.
 *	O : the oobsize of the NAND chip.
 *	M : the metasize of per page.
 *
 *	The formula is :
 *		E * G * N
 *	      ------------ <= (O - M)
 *                  8
 *
 *      So, we get E by:
 *                    (O - M) * 8
 *              E <= -------------
 *                       G * N
 */
static inline int get_ecc_strength(struct gpmi_nand_data *this)
{
	struct bch_geometry *geo = &this->bch_geometry;
	struct mtd_info	*mtd = &this->mtd;
	int ecc_strength;

	ecc_strength = ((mtd->oobsize - geo->metadata_size) * 8)
			/ (geo->gf_len * geo->ecc_chunk_count);

	/* We need the minor even number. */
	return round_down(ecc_strength, 2);
}

int common_nfc_set_geometry(struct gpmi_nand_data *this)
{
	struct bch_geometry *geo = &this->bch_geometry;
	struct mtd_info *mtd = &this->mtd;
	unsigned int metadata_size;
	unsigned int status_size;
	unsigned int block_mark_bit_offset;

	/*
	 * The size of the metadata can be changed, though we set it to 10
	 * bytes now. But it can't be too large, because we have to save
	 * enough space for BCH.
	 */
	geo->metadata_size = 10;

	/* The default for the length of Galois Field. */
	geo->gf_len = 13;

	/* The default for chunk size. There is no oobsize greater then 512. */
	geo->ecc_chunk_size = 512;
	while (geo->ecc_chunk_size < mtd->oobsize)
		geo->ecc_chunk_size *= 2; /* keep C >= O */

	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;

	/* We use the same ECC strength for all chunks. */
	geo->ecc_strength = get_ecc_strength(this);
	if (!geo->ecc_strength) {
		pr_err("We get a wrong ECC strength.\n");
		return -EINVAL;
	}

	geo->page_size = mtd->writesize + mtd->oobsize;
	geo->payload_size = mtd->writesize;

	/*
	 * The auxiliary buffer contains the metadata and the ECC status. The
	 * metadata is padded to the nearest 32-bit boundary. The ECC status
	 * contains one byte for every ECC chunk, and is also padded to the
	 * nearest 32-bit boundary.
	 */
	metadata_size = ALIGN(geo->metadata_size, 4);
	status_size   = ALIGN(geo->ecc_chunk_count, 4);

	geo->auxiliary_size = metadata_size + status_size;
	geo->auxiliary_status_offset = metadata_size;

	if (!this->swap_block_mark)
		return 0;

	/*
	 * We need to compute the byte and bit offsets of
	 * the physical block mark within the ECC-based view of the page.
	 *
	 * NAND chip with 2K page shows below:
	 *                                             (Block Mark)
	 *                                                   |      |
	 *                                                   |  D   |
	 *                                                   |<---->|
	 *                                                   V      V
	 *    +---+----------+-+----------+-+----------+-+----------+-+
	 *    | M |   data   |E|   data   |E|   data   |E|   data   |E|
	 *    +---+----------+-+----------+-+----------+-+----------+-+
	 *
	 * The position of block mark moves forward in the ECC-based view
	 * of page, and the delta is:
	 *
	 *                   E * G * (N - 1)
	 *             D = (---------------- + M)
	 *                          8
	 *
	 * With the formula to compute the ECC strength, and the condition
	 *       : C >= O         (C is the ecc chunk size)
	 *
	 * It's easy to deduce to the following result:
	 *
	 *         E * G       (O - M)      C - M         C - M
	 *      ----------- <= ------- <=  --------  <  ---------
	 *           8            N           N          (N - 1)
	 *
	 *  So, we get:
	 *
	 *                   E * G * (N - 1)
	 *             D = (---------------- + M) < C
	 *                          8
	 *
	 *  The above inequality means the position of block mark
	 *  within the ECC-based view of the page is still in the data chunk,
	 *  and it's NOT in the ECC bits of the chunk.
	 *
	 *  Use the following to compute the bit position of the
	 *  physical block mark within the ECC-based view of the page:
	 *          (page_size - D) * 8
	 *
	 *  --Huang Shijie
	 */
	block_mark_bit_offset = mtd->writesize * 8 -
		(geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1)
				+ geo->metadata_size * 8);

	geo->block_mark_byte_offset = block_mark_bit_offset / 8;
	geo->block_mark_bit_offset  = block_mark_bit_offset % 8;
	return 0;
}

struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
{
	int chipnr = this->current_chip;

	return this->dma_chans[chipnr];
}

/* Can we use the upper's buffer directly for DMA? */
void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr)
{
	struct scatterlist *sgl = &this->data_sgl;
	int ret;

	this->direct_dma_map_ok = true;

	/* first try to map the upper buffer directly */
	sg_init_one(sgl, this->upper_buf, this->upper_len);
	ret = dma_map_sg(this->dev, sgl, 1, dr);
	if (ret == 0) {
		/* We have to use our own DMA buffer. */
		sg_init_one(sgl, this->data_buffer_dma, PAGE_SIZE);

		if (dr == DMA_TO_DEVICE)
			memcpy(this->data_buffer_dma, this->upper_buf,
				this->upper_len);

		ret = dma_map_sg(this->dev, sgl, 1, dr);
		if (ret == 0)
			pr_err("map failed.\n");

		this->direct_dma_map_ok = false;
	}
}

/* This will be called after the DMA operation is finished. */
static void dma_irq_callback(void *param)
{
	struct gpmi_nand_data *this = param;
	struct completion *dma_c = &this->dma_done;

	complete(dma_c);

	switch (this->dma_type) {
	case DMA_FOR_COMMAND:
		dma_unmap_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE);
		break;

	case DMA_FOR_READ_DATA:
		dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_FROM_DEVICE);
		if (this->direct_dma_map_ok == false)
			memcpy(this->upper_buf, this->data_buffer_dma,
				this->upper_len);
		break;

	case DMA_FOR_WRITE_DATA:
		dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_TO_DEVICE);
		break;

	case DMA_FOR_READ_ECC_PAGE:
	case DMA_FOR_WRITE_ECC_PAGE:
		/* We have to wait the BCH interrupt to finish. */
		break;

	default:
		pr_err("in wrong DMA operation.\n");
	}
}

int start_dma_without_bch_irq(struct gpmi_nand_data *this,
				struct dma_async_tx_descriptor *desc)
{
	struct completion *dma_c = &this->dma_done;
	int err;

	init_completion(dma_c);

	desc->callback		= dma_irq_callback;
	desc->callback_param	= this;
	dmaengine_submit(desc);
	dma_async_issue_pending(get_dma_chan(this));

	/* Wait for the interrupt from the DMA block. */
	err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000));
	if (!err) {
		pr_err("DMA timeout, last DMA :%d\n", this->last_dma_type);
		gpmi_dump_info(this);
		return -ETIMEDOUT;
	}
	return 0;
}

/*
 * This function is used in BCH reading or BCH writing pages.
 * It will wait for the BCH interrupt as long as ONE second.
 * Actually, we must wait for two interrupts :
 *	[1] firstly the DMA interrupt and
 *	[2] secondly the BCH interrupt.
 */
int start_dma_with_bch_irq(struct gpmi_nand_data *this,
			struct dma_async_tx_descriptor *desc)
{
	struct completion *bch_c = &this->bch_done;
	int err;

	/* Prepare to receive an interrupt from the BCH block. */
	init_completion(bch_c);

	/* start the DMA */
	start_dma_without_bch_irq(this, desc);

	/* Wait for the interrupt from the BCH block. */
	err = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000));
	if (!err) {
		pr_err("BCH timeout, last DMA :%d\n", this->last_dma_type);
		gpmi_dump_info(this);
		return -ETIMEDOUT;
	}
	return 0;
}

static int __devinit
acquire_register_block(struct gpmi_nand_data *this, const char *res_name)
{
	struct platform_device *pdev = this->pdev;
	struct resources *res = &this->resources;
	struct resource *r;
	void *p;

	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
	if (!r) {
		pr_err("Can't get resource for %s\n", res_name);
		return -ENXIO;
	}

	p = ioremap(r->start, resource_size(r));
	if (!p) {
		pr_err("Can't remap %s\n", res_name);
		return -ENOMEM;
	}

	if (!strcmp(res_name, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME))
		res->gpmi_regs = p;
	else if (!strcmp(res_name, GPMI_NAND_BCH_REGS_ADDR_RES_NAME))
		res->bch_regs = p;
	else
		pr_err("unknown resource name : %s\n", res_name);

	return 0;
}

static void release_register_block(struct gpmi_nand_data *this)
{
	struct resources *res = &this->resources;
	if (res->gpmi_regs)
		iounmap(res->gpmi_regs);
	if (res->bch_regs)
		iounmap(res->bch_regs);
	res->gpmi_regs = NULL;
	res->bch_regs = NULL;
}

static int __devinit
acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h)
{
	struct platform_device *pdev = this->pdev;
	struct resources *res = &this->resources;
	const char *res_name = GPMI_NAND_BCH_INTERRUPT_RES_NAME;
	struct resource *r;
	int err;

	r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
	if (!r) {
		pr_err("Can't get resource for %s\n", res_name);
		return -ENXIO;
	}

	err = request_irq(r->start, irq_h, 0, res_name, this);
	if (err) {
		pr_err("Can't own %s\n", res_name);
		return err;
	}

	res->bch_low_interrupt = r->start;
	res->bch_high_interrupt = r->end;
	return 0;
}

static void release_bch_irq(struct gpmi_nand_data *this)
{
	struct resources *res = &this->resources;
	int i = res->bch_low_interrupt;

	for (; i <= res->bch_high_interrupt; i++)
		free_irq(i, this);
}

static bool gpmi_dma_filter(struct dma_chan *chan, void *param)
{
	struct gpmi_nand_data *this = param;
	int dma_channel = (int)this->private;

	if (!mxs_dma_is_apbh(chan))
		return false;
	/*
	 * only catch the GPMI dma channels :
	 *	for mx23 :	MX23_DMA_GPMI0 ~ MX23_DMA_GPMI3
	 *		(These four channels share the same IRQ!)
	 *
	 *	for mx28 :	MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7
	 *		(These eight channels share the same IRQ!)
	 */
	if (dma_channel == chan->chan_id) {
		chan->private = &this->dma_data;
		return true;
	}
	return false;
}

static void release_dma_channels(struct gpmi_nand_data *this)
{
	unsigned int i;
	for (i = 0; i < DMA_CHANS; i++)
		if (this->dma_chans[i]) {
			dma_release_channel(this->dma_chans[i]);
			this->dma_chans[i] = NULL;
		}
}

static int __devinit acquire_dma_channels(struct gpmi_nand_data *this)
{
	struct platform_device *pdev = this->pdev;
	struct resource *r_dma;
	struct device_node *dn;
	int dma_channel;
	unsigned int ret;
	struct dma_chan *dma_chan;
	dma_cap_mask_t mask;

	/* dma channel, we only use the first one. */
	dn = pdev->dev.of_node;
	ret = of_property_read_u32(dn, "fsl,gpmi-dma-channel", &dma_channel);
	if (ret) {
		pr_err("unable to get DMA channel from dt.\n");
		goto acquire_err;
	}
	this->private = (void *)dma_channel;

	/* gpmi dma interrupt */
	r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
					GPMI_NAND_DMA_INTERRUPT_RES_NAME);
	if (!r_dma) {
		pr_err("Can't get resource for DMA\n");
		goto acquire_err;
	}
	this->dma_data.chan_irq = r_dma->start;

	/* request dma channel */
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
	if (!dma_chan) {
		pr_err("dma_request_channel failed.\n");
		goto acquire_err;
	}

	this->dma_chans[0] = dma_chan;
	return 0;

acquire_err:
	release_dma_channels(this);
	return -EINVAL;
}

static int __devinit acquire_resources(struct gpmi_nand_data *this)
{
	struct resources *res = &this->resources;
	struct pinctrl *pinctrl;
	int ret;

	ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME);
	if (ret)
		goto exit_regs;

	ret = acquire_register_block(this, GPMI_NAND_BCH_REGS_ADDR_RES_NAME);
	if (ret)
		goto exit_regs;

	ret = acquire_bch_irq(this, bch_irq);
	if (ret)
		goto exit_regs;

	ret = acquire_dma_channels(this);
	if (ret)
		goto exit_dma_channels;

	pinctrl = devm_pinctrl_get_select_default(&this->pdev->dev);
	if (IS_ERR(pinctrl)) {
		ret = PTR_ERR(pinctrl);
		goto exit_pin;
	}

	res->clock = clk_get(&this->pdev->dev, NULL);
	if (IS_ERR(res->clock)) {
		pr_err("can not get the clock\n");
		ret = -ENOENT;
		goto exit_clock;
	}
	return 0;

exit_clock:
exit_pin:
	release_dma_channels(this);
exit_dma_channels:
	release_bch_irq(this);
exit_regs:
	release_register_block(this);
	return ret;
}

static void release_resources(struct gpmi_nand_data *this)
{
	struct resources *r = &this->resources;

	clk_put(r->clock);
	release_register_block(this);
	release_bch_irq(this);
	release_dma_channels(this);
}

static int __devinit init_hardware(struct gpmi_nand_data *this)
{
	int ret;

	/*
	 * This structure contains the "safe" GPMI timing that should succeed
	 * with any NAND Flash device
	 * (although, with less-than-optimal performance).
	 */
	struct nand_timing  safe_timing = {
		.data_setup_in_ns        = 80,
		.data_hold_in_ns         = 60,
		.address_setup_in_ns     = 25,
		.gpmi_sample_delay_in_ns =  6,
		.tREA_in_ns              = -1,
		.tRLOH_in_ns             = -1,
		.tRHOH_in_ns             = -1,
	};

	/* Initialize the hardwares. */
	ret = gpmi_init(this);
	if (ret)
		return ret;

	this->timing = safe_timing;
	return 0;
}

static int read_page_prepare(struct gpmi_nand_data *this,
			void *destination, unsigned length,
			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
			void **use_virt, dma_addr_t *use_phys)
{
	struct device *dev = this->dev;

	if (virt_addr_valid(destination)) {
		dma_addr_t dest_phys;

		dest_phys = dma_map_single(dev, destination,
						length, DMA_FROM_DEVICE);
		if (dma_mapping_error(dev, dest_phys)) {
			if (alt_size < length) {
				pr_err("Alternate buffer is too small\n");
				return -ENOMEM;
			}
			goto map_failed;
		}
		*use_virt = destination;
		*use_phys = dest_phys;
		this->direct_dma_map_ok = true;
		return 0;
	}

map_failed:
	*use_virt = alt_virt;
	*use_phys = alt_phys;
	this->direct_dma_map_ok = false;
	return 0;
}

static inline void read_page_end(struct gpmi_nand_data *this,
			void *destination, unsigned length,
			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
			void *used_virt, dma_addr_t used_phys)
{
	if (this->direct_dma_map_ok)
		dma_unmap_single(this->dev, used_phys, length, DMA_FROM_DEVICE);
}

static inline void read_page_swap_end(struct gpmi_nand_data *this,
			void *destination, unsigned length,
			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
			void *used_virt, dma_addr_t used_phys)
{
	if (!this->direct_dma_map_ok)
		memcpy(destination, alt_virt, length);
}

static int send_page_prepare(struct gpmi_nand_data *this,
			const void *source, unsigned length,
			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
			const void **use_virt, dma_addr_t *use_phys)
{
	struct device *dev = this->dev;

	if (virt_addr_valid(source)) {
		dma_addr_t source_phys;

		source_phys = dma_map_single(dev, (void *)source, length,
						DMA_TO_DEVICE);
		if (dma_mapping_error(dev, source_phys)) {
			if (alt_size < length) {
				pr_err("Alternate buffer is too small\n");
				return -ENOMEM;
			}
			goto map_failed;
		}
		*use_virt = source;
		*use_phys = source_phys;
		return 0;
	}
map_failed:
	/*
	 * Copy the content of the source buffer into the alternate
	 * buffer and set up the return values accordingly.
	 */
	memcpy(alt_virt, source, length);

	*use_virt = alt_virt;
	*use_phys = alt_phys;
	return 0;
}

static void send_page_end(struct gpmi_nand_data *this,
			const void *source, unsigned length,
			void *alt_virt, dma_addr_t alt_phys, unsigned alt_size,
			const void *used_virt, dma_addr_t used_phys)
{
	struct device *dev = this->dev;
	if (used_virt == source)
		dma_unmap_single(dev, used_phys, length, DMA_TO_DEVICE);
}

static void gpmi_free_dma_buffer(struct gpmi_nand_data *this)
{
	struct device *dev = this->dev;

	if (this->page_buffer_virt && virt_addr_valid(this->page_buffer_virt))
		dma_free_coherent(dev, this->page_buffer_size,
					this->page_buffer_virt,
					this->page_buffer_phys);
	kfree(this->cmd_buffer);
	kfree(this->data_buffer_dma);

	this->cmd_buffer	= NULL;
	this->data_buffer_dma	= NULL;
	this->page_buffer_virt	= NULL;
	this->page_buffer_size	=  0;
}

/* Allocate the DMA buffers */
static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
{
	struct bch_geometry *geo = &this->bch_geometry;
	struct device *dev = this->dev;

	/* [1] Allocate a command buffer. PAGE_SIZE is enough. */
	this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA);
	if (this->cmd_buffer == NULL)
		goto error_alloc;

	/* [2] Allocate a read/write data buffer. PAGE_SIZE is enough. */
	this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA);
	if (this->data_buffer_dma == NULL)
		goto error_alloc;

	/*
	 * [3] Allocate the page buffer.
	 *
	 * Both the payload buffer and the auxiliary buffer must appear on
	 * 32-bit boundaries. We presume the size of the payload buffer is a
	 * power of two and is much larger than four, which guarantees the
	 * auxiliary buffer will appear on a 32-bit boundary.
	 */
	this->page_buffer_size = geo->payload_size + geo->auxiliary_size;
	this->page_buffer_virt = dma_alloc_coherent(dev, this->page_buffer_size,
					&this->page_buffer_phys, GFP_DMA);
	if (!this->page_buffer_virt)
		goto error_alloc;


	/* Slice up the page buffer. */
	this->payload_virt = this->page_buffer_virt;
	this->payload_phys = this->page_buffer_phys;
	this->auxiliary_virt = this->payload_virt + geo->payload_size;
	this->auxiliary_phys = this->payload_phys + geo->payload_size;
	return 0;

error_alloc:
	gpmi_free_dma_buffer(this);
	pr_err("allocate DMA buffer ret!!\n");
	return -ENOMEM;
}

static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;
	int ret;

	/*
	 * Every operation begins with a command byte and a series of zero or
	 * more address bytes. These are distinguished by either the Address
	 * Latch Enable (ALE) or Command Latch Enable (CLE) signals being
	 * asserted. When MTD is ready to execute the command, it will deassert
	 * both latch enables.
	 *
	 * Rather than run a separate DMA operation for every single byte, we
	 * queue them up and run a single DMA operation for the entire series
	 * of command and data bytes. NAND_CMD_NONE means the END of the queue.
	 */
	if ((ctrl & (NAND_ALE | NAND_CLE))) {
		if (data != NAND_CMD_NONE)
			this->cmd_buffer[this->command_length++] = data;
		return;
	}

	if (!this->command_length)
		return;

	ret = gpmi_send_command(this);
	if (ret)
		pr_err("Chip: %u, Error %d\n", this->current_chip, ret);

	this->command_length = 0;
}

static int gpmi_dev_ready(struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;

	return gpmi_is_ready(this, this->current_chip);
}

static void gpmi_select_chip(struct mtd_info *mtd, int chipnr)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;

	if ((this->current_chip < 0) && (chipnr >= 0))
		gpmi_begin(this);
	else if ((this->current_chip >= 0) && (chipnr < 0))
		gpmi_end(this);

	this->current_chip = chipnr;
}

static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;

	pr_debug("len is %d\n", len);
	this->upper_buf	= buf;
	this->upper_len	= len;

	gpmi_read_data(this);
}

static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;

	pr_debug("len is %d\n", len);
	this->upper_buf	= (uint8_t *)buf;
	this->upper_len	= len;

	gpmi_send_data(this);
}

static uint8_t gpmi_read_byte(struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;
	uint8_t *buf = this->data_buffer_dma;

	gpmi_read_buf(mtd, buf, 1);
	return buf[0];
}

/*
 * Handles block mark swapping.
 * It can be called in swapping the block mark, or swapping it back,
 * because the the operations are the same.
 */
static void block_mark_swapping(struct gpmi_nand_data *this,
				void *payload, void *auxiliary)
{
	struct bch_geometry *nfc_geo = &this->bch_geometry;
	unsigned char *p;
	unsigned char *a;
	unsigned int  bit;
	unsigned char mask;
	unsigned char from_data;
	unsigned char from_oob;

	if (!this->swap_block_mark)
		return;

	/*
	 * If control arrives here, we're swapping. Make some convenience
	 * variables.
	 */
	bit = nfc_geo->block_mark_bit_offset;
	p   = payload + nfc_geo->block_mark_byte_offset;
	a   = auxiliary;

	/*
	 * Get the byte from the data area that overlays the block mark. Since
	 * the ECC engine applies its own view to the bits in the page, the
	 * physical block mark won't (in general) appear on a byte boundary in
	 * the data.
	 */
	from_data = (p[0] >> bit) | (p[1] << (8 - bit));

	/* Get the byte from the OOB. */
	from_oob = a[0];

	/* Swap them. */
	a[0] = from_data;

	mask = (0x1 << bit) - 1;
	p[0] = (p[0] & mask) | (from_oob << bit);

	mask = ~0 << bit;
	p[1] = (p[1] & mask) | (from_oob >> (8 - bit));
}

static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
				uint8_t *buf, int oob_required, int page)
{
	struct gpmi_nand_data *this = chip->priv;
	struct bch_geometry *nfc_geo = &this->bch_geometry;
	void          *payload_virt;
	dma_addr_t    payload_phys;
	void          *auxiliary_virt;
	dma_addr_t    auxiliary_phys;
	unsigned int  i;
	unsigned char *status;
	unsigned int  failed;
	unsigned int  corrected;
	int           ret;

	pr_debug("page number is : %d\n", page);
	ret = read_page_prepare(this, buf, mtd->writesize,
					this->payload_virt, this->payload_phys,
					nfc_geo->payload_size,
					&payload_virt, &payload_phys);
	if (ret) {
		pr_err("Inadequate DMA buffer\n");
		ret = -ENOMEM;
		return ret;
	}
	auxiliary_virt = this->auxiliary_virt;
	auxiliary_phys = this->auxiliary_phys;

	/* go! */
	ret = gpmi_read_page(this, payload_phys, auxiliary_phys);
	read_page_end(this, buf, mtd->writesize,
			this->payload_virt, this->payload_phys,
			nfc_geo->payload_size,
			payload_virt, payload_phys);
	if (ret) {
		pr_err("Error in ECC-based read: %d\n", ret);
		goto exit_nfc;
	}

	/* handle the block mark swapping */
	block_mark_swapping(this, payload_virt, auxiliary_virt);

	/* Loop over status bytes, accumulating ECC status. */
	failed		= 0;
	corrected	= 0;
	status		= auxiliary_virt + nfc_geo->auxiliary_status_offset;

	for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) {
		if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED))
			continue;

		if (*status == STATUS_UNCORRECTABLE) {
			failed++;
			continue;
		}
		corrected += *status;
	}

	/*
	 * Propagate ECC status to the owning MTD only when failed or
	 * corrected times nearly reaches our ECC correction threshold.
	 */
	if (failed || corrected >= (nfc_geo->ecc_strength - 1)) {
		mtd->ecc_stats.failed    += failed;
		mtd->ecc_stats.corrected += corrected;
	}

	if (oob_required) {
		/*
		 * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob()
		 * for details about our policy for delivering the OOB.
		 *
		 * We fill the caller's buffer with set bits, and then copy the
		 * block mark to th caller's buffer. Note that, if block mark
		 * swapping was necessary, it has already been done, so we can
		 * rely on the first byte of the auxiliary buffer to contain
		 * the block mark.
		 */
		memset(chip->oob_poi, ~0, mtd->oobsize);
		chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0];

		read_page_swap_end(this, buf, mtd->writesize,
				this->payload_virt, this->payload_phys,
				nfc_geo->payload_size,
				payload_virt, payload_phys);
	}
exit_nfc:
	return ret;
}

static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
				const uint8_t *buf, int oob_required)
{
	struct gpmi_nand_data *this = chip->priv;
	struct bch_geometry *nfc_geo = &this->bch_geometry;
	const void *payload_virt;
	dma_addr_t payload_phys;
	const void *auxiliary_virt;
	dma_addr_t auxiliary_phys;
	int        ret;

	pr_debug("ecc write page.\n");
	if (this->swap_block_mark) {
		/*
		 * If control arrives here, we're doing block mark swapping.
		 * Since we can't modify the caller's buffers, we must copy them
		 * into our own.
		 */
		memcpy(this->payload_virt, buf, mtd->writesize);
		payload_virt = this->payload_virt;
		payload_phys = this->payload_phys;

		memcpy(this->auxiliary_virt, chip->oob_poi,
				nfc_geo->auxiliary_size);
		auxiliary_virt = this->auxiliary_virt;
		auxiliary_phys = this->auxiliary_phys;

		/* Handle block mark swapping. */
		block_mark_swapping(this,
				(void *) payload_virt, (void *) auxiliary_virt);
	} else {
		/*
		 * If control arrives here, we're not doing block mark swapping,
		 * so we can to try and use the caller's buffers.
		 */
		ret = send_page_prepare(this,
				buf, mtd->writesize,
				this->payload_virt, this->payload_phys,
				nfc_geo->payload_size,
				&payload_virt, &payload_phys);
		if (ret) {
			pr_err("Inadequate payload DMA buffer\n");
			return;
		}

		ret = send_page_prepare(this,
				chip->oob_poi, mtd->oobsize,
				this->auxiliary_virt, this->auxiliary_phys,
				nfc_geo->auxiliary_size,
				&auxiliary_virt, &auxiliary_phys);
		if (ret) {
			pr_err("Inadequate auxiliary DMA buffer\n");
			goto exit_auxiliary;
		}
	}

	/* Ask the NFC. */
	ret = gpmi_send_page(this, payload_phys, auxiliary_phys);
	if (ret)
		pr_err("Error in ECC-based write: %d\n", ret);

	if (!this->swap_block_mark) {
		send_page_end(this, chip->oob_poi, mtd->oobsize,
				this->auxiliary_virt, this->auxiliary_phys,
				nfc_geo->auxiliary_size,
				auxiliary_virt, auxiliary_phys);
exit_auxiliary:
		send_page_end(this, buf, mtd->writesize,
				this->payload_virt, this->payload_phys,
				nfc_geo->payload_size,
				payload_virt, payload_phys);
	}
}

/*
 * There are several places in this driver where we have to handle the OOB and
 * block marks. This is the function where things are the most complicated, so
 * this is where we try to explain it all. All the other places refer back to
 * here.
 *
 * These are the rules, in order of decreasing importance:
 *
 * 1) Nothing the caller does can be allowed to imperil the block mark.
 *
 * 2) In read operations, the first byte of the OOB we return must reflect the
 *    true state of the block mark, no matter where that block mark appears in
 *    the physical page.
 *
 * 3) ECC-based read operations return an OOB full of set bits (since we never
 *    allow ECC-based writes to the OOB, it doesn't matter what ECC-based reads
 *    return).
 *
 * 4) "Raw" read operations return a direct view of the physical bytes in the
 *    page, using the conventional definition of which bytes are data and which
 *    are OOB. This gives the caller a way to see the actual, physical bytes
 *    in the page, without the distortions applied by our ECC engine.
 *
 *
 * What we do for this specific read operation depends on two questions:
 *
 * 1) Are we doing a "raw" read, or an ECC-based read?
 *
 * 2) Are we using block mark swapping or transcription?
 *
 * There are four cases, illustrated by the following Karnaugh map:
 *
 *                    |           Raw           |         ECC-based       |
 *       -------------+-------------------------+-------------------------+
 *                    | Read the conventional   |                         |
 *                    | OOB at the end of the   |                         |
 *       Swapping     | page and return it. It  |                         |
 *                    | contains exactly what   |                         |
 *                    | we want.                | Read the block mark and |
 *       -------------+-------------------------+ return it in a buffer   |
 *                    | Read the conventional   | full of set bits.       |
 *                    | OOB at the end of the   |                         |
 *                    | page and also the block |                         |
 *       Transcribing | mark in the metadata.   |                         |
 *                    | Copy the block mark     |                         |
 *                    | into the first byte of  |                         |
 *                    | the OOB.                |                         |
 *       -------------+-------------------------+-------------------------+
 *
 * Note that we break rule #4 in the Transcribing/Raw case because we're not
 * giving an accurate view of the actual, physical bytes in the page (we're
 * overwriting the block mark). That's OK because it's more important to follow
 * rule #2.
 *
 * It turns out that knowing whether we want an "ECC-based" or "raw" read is not
 * easy. When reading a page, for example, the NAND Flash MTD code calls our
 * ecc.read_page or ecc.read_page_raw function. Thus, the fact that MTD wants an
 * ECC-based or raw view of the page is implicit in which function it calls
 * (there is a similar pair of ECC-based/raw functions for writing).
 *
 * Since MTD assumes the OOB is not covered by ECC, there is no pair of
 * ECC-based/raw functions for reading or or writing the OOB. The fact that the
 * caller wants an ECC-based or raw view of the page is not propagated down to
 * this driver.
 */
static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
				int page)
{
	struct gpmi_nand_data *this = chip->priv;

	pr_debug("page number is %d\n", page);
	/* clear the OOB buffer */
	memset(chip->oob_poi, ~0, mtd->oobsize);

	/* Read out the conventional OOB. */
	chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);

	/*
	 * Now, we want to make sure the block mark is correct. In the
	 * Swapping/Raw case, we already have it. Otherwise, we need to
	 * explicitly read it.
	 */
	if (!this->swap_block_mark) {
		/* Read the block mark into the first byte of the OOB buffer. */
		chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
		chip->oob_poi[0] = chip->read_byte(mtd);
	}

	return 0;
}

static int
gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
{
	/*
	 * The BCH will use all the (page + oob).
	 * Our gpmi_hw_ecclayout can only prohibit the JFFS2 to write the oob.
	 * But it can not stop some ioctls such MEMWRITEOOB which uses
	 * MTD_OPS_PLACE_OOB. So We have to implement this function to prohibit
	 * these ioctls too.
	 */
	return -EPERM;
}

static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;
	int block, ret = 0;
	uint8_t *block_mark;
	int column, page, status, chipnr;

	/* Get block number */
	block = (int)(ofs >> chip->bbt_erase_shift);
	if (chip->bbt)
		chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);

	/* Do we have a flash based bad block table ? */
	if (chip->bbt_options & NAND_BBT_USE_FLASH)
		ret = nand_update_bbt(mtd, ofs);
	else {
		chipnr = (int)(ofs >> chip->chip_shift);
		chip->select_chip(mtd, chipnr);

		column = this->swap_block_mark ? mtd->writesize : 0;

		/* Write the block mark. */
		block_mark = this->data_buffer_dma;
		block_mark[0] = 0; /* bad block marker */

		/* Shift to get page */
		page = (int)(ofs >> chip->page_shift);

		chip->cmdfunc(mtd, NAND_CMD_SEQIN, column, page);
		chip->write_buf(mtd, block_mark, 1);
		chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);

		status = chip->waitfunc(mtd, chip);
		if (status & NAND_STATUS_FAIL)
			ret = -EIO;

		chip->select_chip(mtd, -1);
	}
	if (!ret)
		mtd->ecc_stats.badblocks++;

	return ret;
}

static int nand_boot_set_geometry(struct gpmi_nand_data *this)
{
	struct boot_rom_geometry *geometry = &this->rom_geometry;

	/*
	 * Set the boot block stride size.
	 *
	 * In principle, we should be reading this from the OTP bits, since
	 * that's where the ROM is going to get it. In fact, we don't have any
	 * way to read the OTP bits, so we go with the default and hope for the
	 * best.
	 */
	geometry->stride_size_in_pages = 64;

	/*
	 * Set the search area stride exponent.
	 *
	 * In principle, we should be reading this from the OTP bits, since
	 * that's where the ROM is going to get it. In fact, we don't have any
	 * way to read the OTP bits, so we go with the default and hope for the
	 * best.
	 */
	geometry->search_area_stride_exponent = 2;
	return 0;
}

static const char  *fingerprint = "STMP";
static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)
{
	struct boot_rom_geometry *rom_geo = &this->rom_geometry;
	struct device *dev = this->dev;
	struct mtd_info *mtd = &this->mtd;
	struct nand_chip *chip = &this->nand;
	unsigned int search_area_size_in_strides;
	unsigned int stride;
	unsigned int page;
	loff_t byte;
	uint8_t *buffer = chip->buffers->databuf;
	int saved_chip_number;
	int found_an_ncb_fingerprint = false;

	/* Compute the number of strides in a search area. */
	search_area_size_in_strides = 1 << rom_geo->search_area_stride_exponent;

	saved_chip_number = this->current_chip;
	chip->select_chip(mtd, 0);

	/*
	 * Loop through the first search area, looking for the NCB fingerprint.
	 */
	dev_dbg(dev, "Scanning for an NCB fingerprint...\n");

	for (stride = 0; stride < search_area_size_in_strides; stride++) {
		/* Compute the page and byte addresses. */
		page = stride * rom_geo->stride_size_in_pages;
		byte = page   * mtd->writesize;

		dev_dbg(dev, "Looking for a fingerprint in page 0x%x\n", page);

		/*
		 * Read the NCB fingerprint. The fingerprint is four bytes long
		 * and starts in the 12th byte of the page.
		 */
		chip->cmdfunc(mtd, NAND_CMD_READ0, 12, page);
		chip->read_buf(mtd, buffer, strlen(fingerprint));

		/* Look for the fingerprint. */
		if (!memcmp(buffer, fingerprint, strlen(fingerprint))) {
			found_an_ncb_fingerprint = true;
			break;
		}

	}

	chip->select_chip(mtd, saved_chip_number);

	if (found_an_ncb_fingerprint)
		dev_dbg(dev, "\tFound a fingerprint\n");
	else
		dev_dbg(dev, "\tNo fingerprint found\n");
	return found_an_ncb_fingerprint;
}

/* Writes a transcription stamp. */
static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
{
	struct device *dev = this->dev;
	struct boot_rom_geometry *rom_geo = &this->rom_geometry;
	struct mtd_info *mtd = &this->mtd;
	struct nand_chip *chip = &this->nand;
	unsigned int block_size_in_pages;
	unsigned int search_area_size_in_strides;
	unsigned int search_area_size_in_pages;
	unsigned int search_area_size_in_blocks;
	unsigned int block;
	unsigned int stride;
	unsigned int page;
	loff_t       byte;
	uint8_t      *buffer = chip->buffers->databuf;
	int saved_chip_number;
	int status;

	/* Compute the search area geometry. */
	block_size_in_pages = mtd->erasesize / mtd->writesize;
	search_area_size_in_strides = 1 << rom_geo->search_area_stride_exponent;
	search_area_size_in_pages = search_area_size_in_strides *
					rom_geo->stride_size_in_pages;
	search_area_size_in_blocks =
		  (search_area_size_in_pages + (block_size_in_pages - 1)) /
				    block_size_in_pages;

	dev_dbg(dev, "Search Area Geometry :\n");
	dev_dbg(dev, "\tin Blocks : %u\n", search_area_size_in_blocks);
	dev_dbg(dev, "\tin Strides: %u\n", search_area_size_in_strides);
	dev_dbg(dev, "\tin Pages  : %u\n", search_area_size_in_pages);

	/* Select chip 0. */
	saved_chip_number = this->current_chip;
	chip->select_chip(mtd, 0);

	/* Loop over blocks in the first search area, erasing them. */
	dev_dbg(dev, "Erasing the search area...\n");

	for (block = 0; block < search_area_size_in_blocks; block++) {
		/* Compute the page address. */
		page = block * block_size_in_pages;

		/* Erase this block. */
		dev_dbg(dev, "\tErasing block 0x%x\n", block);
		chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
		chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);

		/* Wait for the erase to finish. */
		status = chip->waitfunc(mtd, chip);
		if (status & NAND_STATUS_FAIL)
			dev_err(dev, "[%s] Erase failed.\n", __func__);
	}

	/* Write the NCB fingerprint into the page buffer. */
	memset(buffer, ~0, mtd->writesize);
	memset(chip->oob_poi, ~0, mtd->oobsize);
	memcpy(buffer + 12, fingerprint, strlen(fingerprint));

	/* Loop through the first search area, writing NCB fingerprints. */
	dev_dbg(dev, "Writing NCB fingerprints...\n");
	for (stride = 0; stride < search_area_size_in_strides; stride++) {
		/* Compute the page and byte addresses. */
		page = stride * rom_geo->stride_size_in_pages;
		byte = page   * mtd->writesize;

		/* Write the first page of the current stride. */
		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
		chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
		chip->ecc.write_page_raw(mtd, chip, buffer, 0);
		chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);

		/* Wait for the write to finish. */
		status = chip->waitfunc(mtd, chip);
		if (status & NAND_STATUS_FAIL)
			dev_err(dev, "[%s] Write failed.\n", __func__);
	}

	/* Deselect chip 0. */
	chip->select_chip(mtd, saved_chip_number);
	return 0;
}

static int mx23_boot_init(struct gpmi_nand_data  *this)
{
	struct device *dev = this->dev;
	struct nand_chip *chip = &this->nand;
	struct mtd_info *mtd = &this->mtd;
	unsigned int block_count;
	unsigned int block;
	int     chipnr;
	int     page;
	loff_t  byte;
	uint8_t block_mark;
	int     ret = 0;

	/*
	 * If control arrives here, we can't use block mark swapping, which
	 * means we're forced to use transcription. First, scan for the
	 * transcription stamp. If we find it, then we don't have to do
	 * anything -- the block marks are already transcribed.
	 */
	if (mx23_check_transcription_stamp(this))
		return 0;

	/*
	 * If control arrives here, we couldn't find a transcription stamp, so
	 * so we presume the block marks are in the conventional location.
	 */
	dev_dbg(dev, "Transcribing bad block marks...\n");

	/* Compute the number of blocks in the entire medium. */
	block_count = chip->chipsize >> chip->phys_erase_shift;

	/*
	 * Loop over all the blocks in the medium, transcribing block marks as
	 * we go.
	 */
	for (block = 0; block < block_count; block++) {
		/*
		 * Compute the chip, page and byte addresses for this block's
		 * conventional mark.
		 */
		chipnr = block >> (chip->chip_shift - chip->phys_erase_shift);
		page = block << (chip->phys_erase_shift - chip->page_shift);
		byte = block <<  chip->phys_erase_shift;

		/* Send the command to read the conventional block mark. */
		chip->select_chip(mtd, chipnr);
		chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
		block_mark = chip->read_byte(mtd);
		chip->select_chip(mtd, -1);

		/*
		 * Check if the block is marked bad. If so, we need to mark it
		 * again, but this time the result will be a mark in the
		 * location where we transcribe block marks.
		 */
		if (block_mark != 0xff) {
			dev_dbg(dev, "Transcribing mark in block %u\n", block);
			ret = chip->block_markbad(mtd, byte);
			if (ret)
				dev_err(dev, "Failed to mark block bad with "
							"ret %d\n", ret);
		}
	}

	/* Write the stamp that indicates we've transcribed the block marks. */
	mx23_write_transcription_stamp(this);
	return 0;
}

static int nand_boot_init(struct gpmi_nand_data  *this)
{
	nand_boot_set_geometry(this);

	/* This is ROM arch-specific initilization before the BBT scanning. */
	if (GPMI_IS_MX23(this))
		return mx23_boot_init(this);
	return 0;
}

static int gpmi_set_geometry(struct gpmi_nand_data *this)
{
	int ret;

	/* Free the temporary DMA memory for reading ID. */
	gpmi_free_dma_buffer(this);

	/* Set up the NFC geometry which is used by BCH. */
	ret = bch_set_geometry(this);
	if (ret) {
		pr_err("set geometry ret : %d\n", ret);
		return ret;
	}

	/* Alloc the new DMA buffers according to the pagesize and oobsize */
	return gpmi_alloc_dma_buffer(this);
}

static int gpmi_pre_bbt_scan(struct gpmi_nand_data  *this)
{
	int ret;

	/* Set up swap_block_mark, must be set before the gpmi_set_geometry() */
	if (GPMI_IS_MX23(this))
		this->swap_block_mark = false;
	else
		this->swap_block_mark = true;

	/* Set up the medium geometry */
	ret = gpmi_set_geometry(this);
	if (ret)
		return ret;

	/* Adjust the ECC strength according to the chip. */
	this->nand.ecc.strength = this->bch_geometry.ecc_strength;
	this->mtd.ecc_strength = this->bch_geometry.ecc_strength;

	/* NAND boot init, depends on the gpmi_set_geometry(). */
	return nand_boot_init(this);
}

static int gpmi_scan_bbt(struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd->priv;
	struct gpmi_nand_data *this = chip->priv;
	int ret;

	/* Prepare for the BBT scan. */
	ret = gpmi_pre_bbt_scan(this);
	if (ret)
		return ret;

	/* use the default BBT implementation */
	return nand_default_bbt(mtd);
}

void gpmi_nfc_exit(struct gpmi_nand_data *this)
{
	nand_release(&this->mtd);
	gpmi_free_dma_buffer(this);
}

static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this)
{
	struct mtd_info  *mtd = &this->mtd;
	struct nand_chip *chip = &this->nand;
	struct mtd_part_parser_data ppdata = {};
	int ret;

	/* init current chip */
	this->current_chip	= -1;

	/* init the MTD data structures */
	mtd->priv		= chip;
	mtd->name		= "gpmi-nand";
	mtd->owner		= THIS_MODULE;

	/* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */
	chip->priv		= this;
	chip->select_chip	= gpmi_select_chip;
	chip->cmd_ctrl		= gpmi_cmd_ctrl;
	chip->dev_ready		= gpmi_dev_ready;
	chip->read_byte		= gpmi_read_byte;
	chip->read_buf		= gpmi_read_buf;
	chip->write_buf		= gpmi_write_buf;
	chip->ecc.read_page	= gpmi_ecc_read_page;
	chip->ecc.write_page	= gpmi_ecc_write_page;
	chip->ecc.read_oob	= gpmi_ecc_read_oob;
	chip->ecc.write_oob	= gpmi_ecc_write_oob;
	chip->scan_bbt		= gpmi_scan_bbt;
	chip->badblock_pattern	= &gpmi_bbt_descr;
	chip->block_markbad	= gpmi_block_markbad;
	chip->options		|= NAND_NO_SUBPAGE_WRITE;
	chip->ecc.mode		= NAND_ECC_HW;
	chip->ecc.size		= 1;
	chip->ecc.strength	= 8;
	chip->ecc.layout	= &gpmi_hw_ecclayout;

	/* Allocate a temporary DMA buffer for reading ID in the nand_scan() */
	this->bch_geometry.payload_size = 1024;
	this->bch_geometry.auxiliary_size = 128;
	ret = gpmi_alloc_dma_buffer(this);
	if (ret)
		goto err_out;

	ret = nand_scan(mtd, 1);
	if (ret) {
		pr_err("Chip scan failed\n");
		goto err_out;
	}

	ppdata.of_node = this->pdev->dev.of_node;
	ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
	if (ret)
		goto err_out;
	return 0;

err_out:
	gpmi_nfc_exit(this);
	return ret;
}

static const struct platform_device_id gpmi_ids[] = {
	{ .name = "imx23-gpmi-nand", .driver_data = IS_MX23, },
	{ .name = "imx28-gpmi-nand", .driver_data = IS_MX28, },
	{ .name = "imx6q-gpmi-nand", .driver_data = IS_MX6Q, },
	{},
};

static const struct of_device_id gpmi_nand_id_table[] = {
	{
		.compatible = "fsl,imx23-gpmi-nand",
		.data = (void *)&gpmi_ids[IS_MX23]
	}, {
		.compatible = "fsl,imx28-gpmi-nand",
		.data = (void *)&gpmi_ids[IS_MX28]
	}, {
		.compatible = "fsl,imx6q-gpmi-nand",
		.data = (void *)&gpmi_ids[IS_MX6Q]
	}, {}
};
MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);

static int __devinit gpmi_nand_probe(struct platform_device *pdev)
{
	struct gpmi_nand_data *this;
	const struct of_device_id *of_id;
	int ret;

	of_id = of_match_device(gpmi_nand_id_table, &pdev->dev);
	if (of_id) {
		pdev->id_entry = of_id->data;
	} else {
		pr_err("Failed to find the right device id.\n");
		return -ENOMEM;
	}

	this = kzalloc(sizeof(*this), GFP_KERNEL);
	if (!this) {
		pr_err("Failed to allocate per-device memory\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, this);
	this->pdev  = pdev;
	this->dev   = &pdev->dev;

	ret = acquire_resources(this);
	if (ret)
		goto exit_acquire_resources;

	ret = init_hardware(this);
	if (ret)
		goto exit_nfc_init;

	ret = gpmi_nfc_init(this);
	if (ret)
		goto exit_nfc_init;

	return 0;

exit_nfc_init:
	release_resources(this);
exit_acquire_resources:
	platform_set_drvdata(pdev, NULL);
	kfree(this);
	return ret;
}

static int __exit gpmi_nand_remove(struct platform_device *pdev)
{
	struct gpmi_nand_data *this = platform_get_drvdata(pdev);

	gpmi_nfc_exit(this);
	release_resources(this);
	platform_set_drvdata(pdev, NULL);
	kfree(this);
	return 0;
}

static struct platform_driver gpmi_nand_driver = {
	.driver = {
		.name = "gpmi-nand",
		.of_match_table = gpmi_nand_id_table,
	},
	.probe   = gpmi_nand_probe,
	.remove  = __exit_p(gpmi_nand_remove),
	.id_table = gpmi_ids,
};

static int __init gpmi_nand_init(void)
{
	int err;

	err = platform_driver_register(&gpmi_nand_driver);
	if (err == 0)
		printk(KERN_INFO "GPMI NAND driver registered. (IMX)\n");
	else
		pr_err("i.MX GPMI NAND driver registration failed\n");
	return err;
}

static void __exit gpmi_nand_exit(void)
{
	platform_driver_unregister(&gpmi_nand_driver);
}

module_init(gpmi_nand_init);
module_exit(gpmi_nand_exit);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("i.MX GPMI NAND Flash Controller Driver");
MODULE_LICENSE("GPL");
