/*
 * drivers/dma/fsl_raid.c
 *
 * Freescale RAID Engine device driver
 *
 * Author:
 *	Harninder Rai <harninder.rai@freescale.com>
 *	Naveen Burmi <naveenburmi@freescale.com>
 *
 * Rewrite:
 *	Xuelin Shi <xuelin.shi@freescale.com>
 *
 * Copyright (c) 2010-2014 Freescale Semiconductor, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Freescale Semiconductor nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * ALTERNATIVELY, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") as published by the Free Software
 * Foundation, either version 2 of that License or (at your option) any
 * later version.
 *
 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Theory of operation:
 *
 * General capabilities:
 *	RAID Engine (RE) block is capable of offloading XOR, memcpy and P/Q
 *	calculations required in RAID5 and RAID6 operations. RE driver
 *	registers with Linux's ASYNC layer as dma driver. RE hardware
 *	maintains strict ordering of the requests through chained
 *	command queueing.
 *
 * Data flow:
 *	Software RAID layer of Linux (MD layer) maintains RAID partitions,
 *	strips, stripes etc. It sends requests to the underlying ASYNC layer
 *	which further passes it to RE driver. ASYNC layer decides which request
 *	goes to which job ring of RE hardware. For every request processed by
 *	RAID Engine, driver gets an interrupt unless coalescing is set. The
 *	per job ring interrupt handler checks the status register for errors,
 *	clears the interrupt and leave the post interrupt processing to the irq
 *	thread.
 */
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/dmaengine.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/slab.h>

#include "dmaengine.h"
#include "fsl_raid.h"

#define FSL_RE_MAX_XOR_SRCS	16
#define FSL_RE_MAX_PQ_SRCS	16
#define FSL_RE_MIN_DESCS	256
#define FSL_RE_MAX_DESCS	(4 * FSL_RE_MIN_DESCS)
#define FSL_RE_FRAME_FORMAT	0x1
#define FSL_RE_MAX_DATA_LEN	(1024*1024)

#define to_fsl_re_dma_desc(tx) container_of(tx, struct fsl_re_desc, async_tx)

/* Add descriptors into per chan software queue - submit_q */
static dma_cookie_t fsl_re_tx_submit(struct dma_async_tx_descriptor *tx)
{
	struct fsl_re_desc *desc;
	struct fsl_re_chan *re_chan;
	dma_cookie_t cookie;
	unsigned long flags;

	desc = to_fsl_re_dma_desc(tx);
	re_chan = container_of(tx->chan, struct fsl_re_chan, chan);

	spin_lock_irqsave(&re_chan->desc_lock, flags);
	cookie = dma_cookie_assign(tx);
	list_add_tail(&desc->node, &re_chan->submit_q);
	spin_unlock_irqrestore(&re_chan->desc_lock, flags);

	return cookie;
}

/* Copy descriptor from per chan software queue into hardware job ring */
static void fsl_re_issue_pending(struct dma_chan *chan)
{
	struct fsl_re_chan *re_chan;
	int avail;
	struct fsl_re_desc *desc, *_desc;
	unsigned long flags;

	re_chan = container_of(chan, struct fsl_re_chan, chan);

	spin_lock_irqsave(&re_chan->desc_lock, flags);
	avail = FSL_RE_SLOT_AVAIL(
		in_be32(&re_chan->jrregs->inbring_slot_avail));

	list_for_each_entry_safe(desc, _desc, &re_chan->submit_q, node) {
		if (!avail)
			break;

		list_move_tail(&desc->node, &re_chan->active_q);

		memcpy(&re_chan->inb_ring_virt_addr[re_chan->inb_count],
		       &desc->hwdesc, sizeof(struct fsl_re_hw_desc));

		re_chan->inb_count = (re_chan->inb_count + 1) &
						FSL_RE_RING_SIZE_MASK;
		out_be32(&re_chan->jrregs->inbring_add_job, FSL_RE_ADD_JOB(1));
		avail--;
	}
	spin_unlock_irqrestore(&re_chan->desc_lock, flags);
}

static void fsl_re_desc_done(struct fsl_re_desc *desc)
{
	dma_cookie_complete(&desc->async_tx);
	dma_descriptor_unmap(&desc->async_tx);
	dmaengine_desc_get_callback_invoke(&desc->async_tx, NULL);
}

static void fsl_re_cleanup_descs(struct fsl_re_chan *re_chan)
{
	struct fsl_re_desc *desc, *_desc;
	unsigned long flags;

	spin_lock_irqsave(&re_chan->desc_lock, flags);
	list_for_each_entry_safe(desc, _desc, &re_chan->ack_q, node) {
		if (async_tx_test_ack(&desc->async_tx))
			list_move_tail(&desc->node, &re_chan->free_q);
	}
	spin_unlock_irqrestore(&re_chan->desc_lock, flags);

	fsl_re_issue_pending(&re_chan->chan);
}

static void fsl_re_dequeue(struct tasklet_struct *t)
{
	struct fsl_re_chan *re_chan = from_tasklet(re_chan, t, irqtask);
	struct fsl_re_desc *desc, *_desc;
	struct fsl_re_hw_desc *hwdesc;
	unsigned long flags;
	unsigned int count, oub_count;
	int found;

	fsl_re_cleanup_descs(re_chan);

	spin_lock_irqsave(&re_chan->desc_lock, flags);
	count =	FSL_RE_SLOT_FULL(in_be32(&re_chan->jrregs->oubring_slot_full));
	while (count--) {
		found = 0;
		hwdesc = &re_chan->oub_ring_virt_addr[re_chan->oub_count];
		list_for_each_entry_safe(desc, _desc, &re_chan->active_q,
					 node) {
			/* compare the hw dma addr to find the completed */
			if (desc->hwdesc.lbea32 == hwdesc->lbea32 &&
			    desc->hwdesc.addr_low == hwdesc->addr_low) {
				found = 1;
				break;
			}
		}

		if (found) {
			fsl_re_desc_done(desc);
			list_move_tail(&desc->node, &re_chan->ack_q);
		} else {
			dev_err(re_chan->dev,
				"found hwdesc not in sw queue, discard it\n");
		}

		oub_count = (re_chan->oub_count + 1) & FSL_RE_RING_SIZE_MASK;
		re_chan->oub_count = oub_count;

		out_be32(&re_chan->jrregs->oubring_job_rmvd,
			 FSL_RE_RMVD_JOB(1));
	}
	spin_unlock_irqrestore(&re_chan->desc_lock, flags);
}

/* Per Job Ring interrupt handler */
static irqreturn_t fsl_re_isr(int irq, void *data)
{
	struct fsl_re_chan *re_chan;
	u32 irqstate, status;

	re_chan = dev_get_drvdata((struct device *)data);

	irqstate = in_be32(&re_chan->jrregs->jr_interrupt_status);
	if (!irqstate)
		return IRQ_NONE;

	/*
	 * There's no way in upper layer (read MD layer) to recover from
	 * error conditions except restart everything. In long term we
	 * need to do something more than just crashing
	 */
	if (irqstate & FSL_RE_ERROR) {
		status = in_be32(&re_chan->jrregs->jr_status);
		dev_err(re_chan->dev, "chan error irqstate: %x, status: %x\n",
			irqstate, status);
	}

	/* Clear interrupt */
	out_be32(&re_chan->jrregs->jr_interrupt_status, FSL_RE_CLR_INTR);

	tasklet_schedule(&re_chan->irqtask);

	return IRQ_HANDLED;
}

static enum dma_status fsl_re_tx_status(struct dma_chan *chan,
					dma_cookie_t cookie,
					struct dma_tx_state *txstate)
{
	return dma_cookie_status(chan, cookie, txstate);
}

static void fill_cfd_frame(struct fsl_re_cmpnd_frame *cf, u8 index,
			   size_t length, dma_addr_t addr, bool final)
{
	u32 efrl = length & FSL_RE_CF_LENGTH_MASK;

	efrl |= final << FSL_RE_CF_FINAL_SHIFT;
	cf[index].efrl32 = cpu_to_be32(efrl);
	cf[index].addr_high = cpu_to_be32(upper_32_bits(addr));
	cf[index].addr_low = cpu_to_be32(lower_32_bits(addr));
}

static struct fsl_re_desc *fsl_re_init_desc(struct fsl_re_chan *re_chan,
					    struct fsl_re_desc *desc,
					    void *cf, dma_addr_t paddr)
{
	desc->re_chan = re_chan;
	desc->async_tx.tx_submit = fsl_re_tx_submit;
	dma_async_tx_descriptor_init(&desc->async_tx, &re_chan->chan);
	INIT_LIST_HEAD(&desc->node);

	desc->hwdesc.fmt32 = cpu_to_be32(FSL_RE_FRAME_FORMAT <<
					  FSL_RE_HWDESC_FMT_SHIFT);
	desc->hwdesc.lbea32 = cpu_to_be32(upper_32_bits(paddr));
	desc->hwdesc.addr_low = cpu_to_be32(lower_32_bits(paddr));
	desc->cf_addr = cf;
	desc->cf_paddr = paddr;

	desc->cdb_addr = (void *)(cf + FSL_RE_CF_DESC_SIZE);
	desc->cdb_paddr = paddr + FSL_RE_CF_DESC_SIZE;

	return desc;
}

static struct fsl_re_desc *fsl_re_chan_alloc_desc(struct fsl_re_chan *re_chan,
						  unsigned long flags)
{
	struct fsl_re_desc *desc = NULL;
	void *cf;
	dma_addr_t paddr;
	unsigned long lock_flag;

	fsl_re_cleanup_descs(re_chan);

	spin_lock_irqsave(&re_chan->desc_lock, lock_flag);
	if (!list_empty(&re_chan->free_q)) {
		/* take one desc from free_q */
		desc = list_first_entry(&re_chan->free_q,
					struct fsl_re_desc, node);
		list_del(&desc->node);

		desc->async_tx.flags = flags;
	}
	spin_unlock_irqrestore(&re_chan->desc_lock, lock_flag);

	if (!desc) {
		desc = kzalloc_obj(*desc, GFP_NOWAIT);
		if (!desc)
			return NULL;

		cf = dma_pool_alloc(re_chan->re_dev->cf_desc_pool, GFP_NOWAIT,
				    &paddr);
		if (!cf) {
			kfree(desc);
			return NULL;
		}

		desc = fsl_re_init_desc(re_chan, desc, cf, paddr);
		desc->async_tx.flags = flags;

		spin_lock_irqsave(&re_chan->desc_lock, lock_flag);
		re_chan->alloc_count++;
		spin_unlock_irqrestore(&re_chan->desc_lock, lock_flag);
	}

	return desc;
}

static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq(
		struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
		unsigned int src_cnt, const unsigned char *scf, size_t len,
		unsigned long flags)
{
	struct fsl_re_chan *re_chan;
	struct fsl_re_desc *desc;
	struct fsl_re_xor_cdb *xor;
	struct fsl_re_cmpnd_frame *cf;
	u32 cdb;
	unsigned int i, j;
	unsigned int save_src_cnt = src_cnt;
	int cont_q = 0;

	re_chan = container_of(chan, struct fsl_re_chan, chan);
	if (len > FSL_RE_MAX_DATA_LEN) {
		dev_err(re_chan->dev, "genq tx length %zu, max length %d\n",
			len, FSL_RE_MAX_DATA_LEN);
		return NULL;
	}

	desc = fsl_re_chan_alloc_desc(re_chan, flags);
	if (desc <= 0)
		return NULL;

	if (scf && (flags & DMA_PREP_CONTINUE)) {
		cont_q = 1;
		src_cnt += 1;
	}

	/* Filling xor CDB */
	cdb = FSL_RE_XOR_OPCODE << FSL_RE_CDB_OPCODE_SHIFT;
	cdb |= (src_cnt - 1) << FSL_RE_CDB_NRCS_SHIFT;
	cdb |= FSL_RE_BLOCK_SIZE << FSL_RE_CDB_BLKSIZE_SHIFT;
	cdb |= FSL_RE_INTR_ON_ERROR << FSL_RE_CDB_ERROR_SHIFT;
	cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT;
	xor = desc->cdb_addr;
	xor->cdb32 = cdb;

	if (scf) {
		/* compute q = src0*coef0^src1*coef1^..., * is GF(8) mult */
		for (i = 0; i < save_src_cnt; i++)
			xor->gfm[i] = scf[i];
		if (cont_q)
			xor->gfm[i++] = 1;
	} else {
		/* compute P, that is XOR all srcs */
		for (i = 0; i < src_cnt; i++)
			xor->gfm[i] = 1;
	}

	/* Filling frame 0 of compound frame descriptor with CDB */
	cf = desc->cf_addr;
	fill_cfd_frame(cf, 0, sizeof(*xor), desc->cdb_paddr, 0);

	/* Fill CFD's 1st frame with dest buffer */
	fill_cfd_frame(cf, 1, len, dest, 0);

	/* Fill CFD's rest of the frames with source buffers */
	for (i = 2, j = 0; j < save_src_cnt; i++, j++)
		fill_cfd_frame(cf, i, len, src[j], 0);

	/* Fill the last frame and mark it final */
	if (cont_q)
		fill_cfd_frame(cf, i, len, dest, 1);
	else
		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);

	return &desc->async_tx;
}

/*
 * Prep function for P parity calculation.In RAID Engine terminology,
 * XOR calculation is called GenQ calculation done through GenQ command
 */
static struct dma_async_tx_descriptor *fsl_re_prep_dma_xor(
		struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
		unsigned int src_cnt, size_t len, unsigned long flags)
{
	/* NULL let genq take all coef as 1 */
	return fsl_re_prep_dma_genq(chan, dest, src, src_cnt, NULL, len, flags);
}

/*
 * Prep function for P/Q parity calculation.In RAID Engine terminology,
 * P/Q calculation is called GenQQ done through GenQQ command
 */
static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq(
		struct dma_chan *chan, dma_addr_t *dest, dma_addr_t *src,
		unsigned int src_cnt, const unsigned char *scf, size_t len,
		unsigned long flags)
{
	struct fsl_re_chan *re_chan;
	struct fsl_re_desc *desc;
	struct fsl_re_pq_cdb *pq;
	struct fsl_re_cmpnd_frame *cf;
	u32 cdb;
	u8 *p;
	int gfmq_len, i, j;
	unsigned int save_src_cnt = src_cnt;

	re_chan = container_of(chan, struct fsl_re_chan, chan);
	if (len > FSL_RE_MAX_DATA_LEN) {
		dev_err(re_chan->dev, "pq tx length is %zu, max length is %d\n",
			len, FSL_RE_MAX_DATA_LEN);
		return NULL;
	}

	/*
	 * RE requires at least 2 sources, if given only one source, we pass the
	 * second source same as the first one.
	 * With only one source, generating P is meaningless, only generate Q.
	 */
	if (src_cnt == 1) {
		struct dma_async_tx_descriptor *tx;
		dma_addr_t dma_src[2];
		unsigned char coef[2];

		dma_src[0] = *src;
		coef[0] = *scf;
		dma_src[1] = *src;
		coef[1] = 0;
		tx = fsl_re_prep_dma_genq(chan, dest[1], dma_src, 2, coef, len,
					  flags);
		if (tx)
			desc = to_fsl_re_dma_desc(tx);

		return tx;
	}

	/*
	 * During RAID6 array creation, Linux's MD layer gets P and Q
	 * calculated separately in two steps. But our RAID Engine has
	 * the capability to calculate both P and Q with a single command
	 * Hence to merge well with MD layer, we need to provide a hook
	 * here and call re_jq_prep_dma_genq() function
	 */

	if (flags & DMA_PREP_PQ_DISABLE_P)
		return fsl_re_prep_dma_genq(chan, dest[1], src, src_cnt,
				scf, len, flags);

	if (flags & DMA_PREP_CONTINUE)
		src_cnt += 3;

	desc = fsl_re_chan_alloc_desc(re_chan, flags);
	if (desc <= 0)
		return NULL;

	/* Filling GenQQ CDB */
	cdb = FSL_RE_PQ_OPCODE << FSL_RE_CDB_OPCODE_SHIFT;
	cdb |= (src_cnt - 1) << FSL_RE_CDB_NRCS_SHIFT;
	cdb |= FSL_RE_BLOCK_SIZE << FSL_RE_CDB_BLKSIZE_SHIFT;
	cdb |= FSL_RE_BUFFER_OUTPUT << FSL_RE_CDB_BUFFER_SHIFT;
	cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT;

	pq = desc->cdb_addr;
	pq->cdb32 = cdb;

	p = pq->gfm_q1;
	/* Init gfm_q1[] */
	for (i = 0; i < src_cnt; i++)
		p[i] = 1;

	/* Align gfm[] to 32bit */
	gfmq_len = ALIGN(src_cnt, 4);

	/* Init gfm_q2[] */
	p += gfmq_len;
	for (i = 0; i < src_cnt; i++)
		p[i] = scf[i];

	/* Filling frame 0 of compound frame descriptor with CDB */
	cf = desc->cf_addr;
	fill_cfd_frame(cf, 0, sizeof(struct fsl_re_pq_cdb), desc->cdb_paddr, 0);

	/* Fill CFD's 1st & 2nd frame with dest buffers */
	for (i = 1, j = 0; i < 3; i++, j++)
		fill_cfd_frame(cf, i, len, dest[j], 0);

	/* Fill CFD's rest of the frames with source buffers */
	for (i = 3, j = 0; j < save_src_cnt; i++, j++)
		fill_cfd_frame(cf, i, len, src[j], 0);

	/* PQ computation continuation */
	if (flags & DMA_PREP_CONTINUE) {
		if (src_cnt - save_src_cnt == 3) {
			p[save_src_cnt] = 0;
			p[save_src_cnt + 1] = 0;
			p[save_src_cnt + 2] = 1;
			fill_cfd_frame(cf, i++, len, dest[0], 0);
			fill_cfd_frame(cf, i++, len, dest[1], 0);
			fill_cfd_frame(cf, i++, len, dest[1], 1);
		} else {
			dev_err(re_chan->dev, "PQ tx continuation error!\n");
			return NULL;
		}
	} else {
		/* Mark the last source buffer frame final */
		fill_cfd_frame(cf, i - 1, len, src[j - 1], 1);
	}

	return &desc->async_tx;
}

/*
 * Prep function for memcpy. In RAID Engine, memcpy is done through MOVE
 * command. Logic of this function will need to be modified once multipage
 * support is added in Linux's MD/ASYNC Layer
 */
static struct dma_async_tx_descriptor *fsl_re_prep_dma_memcpy(
		struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
		size_t len, unsigned long flags)
{
	struct fsl_re_chan *re_chan;
	struct fsl_re_desc *desc;
	size_t length;
	struct fsl_re_cmpnd_frame *cf;
	struct fsl_re_move_cdb *move;
	u32 cdb;

	re_chan = container_of(chan, struct fsl_re_chan, chan);

	if (len > FSL_RE_MAX_DATA_LEN) {
		dev_err(re_chan->dev, "cp tx length is %zu, max length is %d\n",
			len, FSL_RE_MAX_DATA_LEN);
		return NULL;
	}

	desc = fsl_re_chan_alloc_desc(re_chan, flags);
	if (desc <= 0)
		return NULL;

	/* Filling move CDB */
	cdb = FSL_RE_MOVE_OPCODE << FSL_RE_CDB_OPCODE_SHIFT;
	cdb |= FSL_RE_BLOCK_SIZE << FSL_RE_CDB_BLKSIZE_SHIFT;
	cdb |= FSL_RE_INTR_ON_ERROR << FSL_RE_CDB_ERROR_SHIFT;
	cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT;

	move = desc->cdb_addr;
	move->cdb32 = cdb;

	/* Filling frame 0 of CFD with move CDB */
	cf = desc->cf_addr;
	fill_cfd_frame(cf, 0, sizeof(*move), desc->cdb_paddr, 0);

	length = min_t(size_t, len, FSL_RE_MAX_DATA_LEN);

	/* Fill CFD's 1st frame with dest buffer */
	fill_cfd_frame(cf, 1, length, dest, 0);

	/* Fill CFD's 2nd frame with src buffer */
	fill_cfd_frame(cf, 2, length, src, 1);

	return &desc->async_tx;
}

static int fsl_re_alloc_chan_resources(struct dma_chan *chan)
{
	struct fsl_re_chan *re_chan;
	struct fsl_re_desc *desc;
	void *cf;
	dma_addr_t paddr;
	int i;

	re_chan = container_of(chan, struct fsl_re_chan, chan);
	for (i = 0; i < FSL_RE_MIN_DESCS; i++) {
		desc = kzalloc_obj(*desc);
		if (!desc)
			break;

		cf = dma_pool_alloc(re_chan->re_dev->cf_desc_pool, GFP_KERNEL,
				    &paddr);
		if (!cf) {
			kfree(desc);
			break;
		}

		INIT_LIST_HEAD(&desc->node);
		fsl_re_init_desc(re_chan, desc, cf, paddr);

		list_add_tail(&desc->node, &re_chan->free_q);
		re_chan->alloc_count++;
	}
	return re_chan->alloc_count;
}

static void fsl_re_free_chan_resources(struct dma_chan *chan)
{
	struct fsl_re_chan *re_chan;
	struct fsl_re_desc *desc;

	re_chan = container_of(chan, struct fsl_re_chan, chan);
	while (re_chan->alloc_count--) {
		desc = list_first_entry(&re_chan->free_q,
					struct fsl_re_desc,
					node);

		list_del(&desc->node);
		dma_pool_free(re_chan->re_dev->cf_desc_pool, desc->cf_addr,
			      desc->cf_paddr);
		kfree(desc);
	}

	if (!list_empty(&re_chan->free_q))
		dev_err(re_chan->dev, "chan resource cannot be cleaned!\n");
}

static int fsl_re_chan_probe(struct platform_device *ofdev,
		      struct device_node *np, u8 q, u32 off)
{
	struct device *dev, *chandev;
	struct fsl_re_drv_private *re_priv;
	struct fsl_re_chan *chan;
	struct dma_device *dma_dev;
	u32 ptr;
	u32 status;
	int ret = 0, rc;
	struct platform_device *chan_ofdev;

	dev = &ofdev->dev;
	re_priv = dev_get_drvdata(dev);
	dma_dev = &re_priv->dma_dev;

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

	/* create platform device for chan node */
	chan_ofdev = of_platform_device_create(np, NULL, dev);
	if (!chan_ofdev) {
		dev_err(dev, "Not able to create ofdev for jr %d\n", q);
		ret = -EINVAL;
		goto err_free;
	}

	/* read reg property from dts */
	rc = of_property_read_u32(np, "reg", &ptr);
	if (rc) {
		dev_err(dev, "Reg property not found in jr %d\n", q);
		ret = -ENODEV;
		goto err_free;
	}

	chan->jrregs = re_priv->base + off + ptr;

	/* read irq property from dts */
	chan->irq = irq_of_parse_and_map(np, 0);
	if (!chan->irq) {
		dev_err(dev, "No IRQ defined for JR %d\n", q);
		ret = -ENODEV;
		goto err_free;
	}

	snprintf(chan->name, sizeof(chan->name), "re_jr%02d", q);

	chandev = &chan_ofdev->dev;
	tasklet_setup(&chan->irqtask, fsl_re_dequeue);

	ret = request_irq(chan->irq, fsl_re_isr, 0, chan->name, chandev);
	if (ret) {
		dev_err(dev, "Unable to register interrupt for JR %d\n", q);
		ret = -EINVAL;
		goto err_free;
	}

	re_priv->re_jrs[q] = chan;
	chan->chan.device = dma_dev;
	chan->chan.private = chan;
	chan->dev = chandev;
	chan->re_dev = re_priv;

	spin_lock_init(&chan->desc_lock);
	INIT_LIST_HEAD(&chan->ack_q);
	INIT_LIST_HEAD(&chan->active_q);
	INIT_LIST_HEAD(&chan->submit_q);
	INIT_LIST_HEAD(&chan->free_q);

	chan->inb_ring_virt_addr = dma_pool_alloc(chan->re_dev->hw_desc_pool,
		GFP_KERNEL, &chan->inb_phys_addr);
	if (!chan->inb_ring_virt_addr) {
		dev_err(dev, "No dma memory for inb_ring_virt_addr\n");
		ret = -ENOMEM;
		goto err_free;
	}

	chan->oub_ring_virt_addr = dma_pool_alloc(chan->re_dev->hw_desc_pool,
		GFP_KERNEL, &chan->oub_phys_addr);
	if (!chan->oub_ring_virt_addr) {
		dev_err(dev, "No dma memory for oub_ring_virt_addr\n");
		ret = -ENOMEM;
		goto err_free_1;
	}

	/* Program the Inbound/Outbound ring base addresses and size */
	out_be32(&chan->jrregs->inbring_base_h,
		 chan->inb_phys_addr & FSL_RE_ADDR_BIT_MASK);
	out_be32(&chan->jrregs->oubring_base_h,
		 chan->oub_phys_addr & FSL_RE_ADDR_BIT_MASK);
	out_be32(&chan->jrregs->inbring_base_l,
		 chan->inb_phys_addr >> FSL_RE_ADDR_BIT_SHIFT);
	out_be32(&chan->jrregs->oubring_base_l,
		 chan->oub_phys_addr >> FSL_RE_ADDR_BIT_SHIFT);
	out_be32(&chan->jrregs->inbring_size,
		 FSL_RE_RING_SIZE << FSL_RE_RING_SIZE_SHIFT);
	out_be32(&chan->jrregs->oubring_size,
		 FSL_RE_RING_SIZE << FSL_RE_RING_SIZE_SHIFT);

	/* Read LIODN value from u-boot */
	status = in_be32(&chan->jrregs->jr_config_1) & FSL_RE_REG_LIODN_MASK;

	/* Program the CFG reg */
	out_be32(&chan->jrregs->jr_config_1,
		 FSL_RE_CFG1_CBSI | FSL_RE_CFG1_CBS0 | status);

	dev_set_drvdata(chandev, chan);

	/* Enable RE/CHAN */
	out_be32(&chan->jrregs->jr_command, FSL_RE_ENABLE);

	return 0;

err_free_1:
	dma_pool_free(chan->re_dev->hw_desc_pool, chan->inb_ring_virt_addr,
		      chan->inb_phys_addr);
err_free:
	return ret;
}

/* Probe function for RAID Engine */
static int fsl_re_probe(struct platform_device *ofdev)
{
	struct fsl_re_ctrl __iomem *re_regs;
	struct fsl_re_drv_private *re_priv;
	struct device_node *child;
	u32 off;
	u8 ridx = 0;
	struct dma_device *dma_dev;
	int rc;
	struct device *dev = &ofdev->dev;

	/* IOMAP the entire RAID Engine region */
	re_regs = devm_platform_ioremap_resource(ofdev, 0);
	if (IS_ERR(re_regs))
		return PTR_ERR(re_regs);

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

	re_priv->base = re_regs;

	/* Program the RE mode */
	out_be32(&re_regs->global_config, FSL_RE_NON_DPAA_MODE);

	/* Program Galois Field polynomial */
	out_be32(&re_regs->galois_field_config, FSL_RE_GFM_POLY);

	dev_info(dev, "version %x, mode %x, gfp %x\n",
		 in_be32(&re_regs->re_version_id),
		 in_be32(&re_regs->global_config),
		 in_be32(&re_regs->galois_field_config));

	dma_dev = &re_priv->dma_dev;
	dma_dev->dev = dev;
	INIT_LIST_HEAD(&dma_dev->channels);
	dma_set_mask(dev, DMA_BIT_MASK(40));

	dma_dev->device_alloc_chan_resources = fsl_re_alloc_chan_resources;
	dma_dev->device_tx_status = fsl_re_tx_status;
	dma_dev->device_issue_pending = fsl_re_issue_pending;

	dma_dev->max_xor = FSL_RE_MAX_XOR_SRCS;
	dma_dev->device_prep_dma_xor = fsl_re_prep_dma_xor;
	dma_cap_set(DMA_XOR, dma_dev->cap_mask);

	dma_dev->max_pq = FSL_RE_MAX_PQ_SRCS;
	dma_dev->device_prep_dma_pq = fsl_re_prep_dma_pq;
	dma_cap_set(DMA_PQ, dma_dev->cap_mask);

	dma_dev->device_prep_dma_memcpy = fsl_re_prep_dma_memcpy;
	dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);

	dma_dev->device_free_chan_resources = fsl_re_free_chan_resources;

	re_priv->total_chans = 0;

	re_priv->cf_desc_pool = dmam_pool_create("fsl_re_cf_desc_pool", dev,
					FSL_RE_CF_CDB_SIZE,
					FSL_RE_CF_CDB_ALIGN, 0);

	if (!re_priv->cf_desc_pool) {
		dev_err(dev, "No memory for fsl re_cf desc pool\n");
		return -ENOMEM;
	}

	re_priv->hw_desc_pool = dmam_pool_create("fsl_re_hw_desc_pool", dev,
			sizeof(struct fsl_re_hw_desc) * FSL_RE_RING_SIZE,
			FSL_RE_FRAME_ALIGN, 0);
	if (!re_priv->hw_desc_pool) {
		dev_err(dev, "No memory for fsl re_hw desc pool\n");
		return -ENOMEM;
	}

	dev_set_drvdata(dev, re_priv);

	/* Parse Device tree to find out the total number of JQs present */
	for_each_compatible_node_scoped(np, NULL, "fsl,raideng-v1.0-job-queue") {
		rc = of_property_read_u32(np, "reg", &off);
		if (rc) {
			dev_err(dev, "Reg property not found in JQ node\n");
			return -ENODEV;
		}
		/* Find out the Job Rings present under each JQ */
		for_each_child_of_node(np, child) {
			rc = of_device_is_compatible(child,
					     "fsl,raideng-v1.0-job-ring");
			if (rc) {
				fsl_re_chan_probe(ofdev, child, ridx++, off);
				re_priv->total_chans++;
			}
		}
	}

	dma_async_device_register(dma_dev);

	return 0;
}

static void fsl_re_remove_chan(struct fsl_re_chan *chan)
{
	tasklet_kill(&chan->irqtask);

	dma_pool_free(chan->re_dev->hw_desc_pool, chan->inb_ring_virt_addr,
		      chan->inb_phys_addr);

	dma_pool_free(chan->re_dev->hw_desc_pool, chan->oub_ring_virt_addr,
		      chan->oub_phys_addr);
}

static void fsl_re_remove(struct platform_device *ofdev)
{
	struct fsl_re_drv_private *re_priv;
	struct device *dev;
	int i;

	dev = &ofdev->dev;
	re_priv = dev_get_drvdata(dev);

	/* Cleanup chan related memory areas */
	for (i = 0; i < re_priv->total_chans; i++)
		fsl_re_remove_chan(re_priv->re_jrs[i]);

	/* Unregister the driver */
	dma_async_device_unregister(&re_priv->dma_dev);
}

static const struct of_device_id fsl_re_ids[] = {
	{ .compatible = "fsl,raideng-v1.0", },
	{}
};
MODULE_DEVICE_TABLE(of, fsl_re_ids);

static struct platform_driver fsl_re_driver = {
	.driver = {
		.name = "fsl-raideng",
		.of_match_table = fsl_re_ids,
	},
	.probe = fsl_re_probe,
	.remove = fsl_re_remove,
};

module_platform_driver(fsl_re_driver);

MODULE_AUTHOR("Harninder Rai <harninder.rai@freescale.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Freescale RAID Engine Device Driver");
