/*
 * 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_irq.h>
#include <linux/of_address.h>
#include <linux/of_platform.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(unsigned long data)
{
	struct fsl_re_chan *re_chan;
	struct fsl_re_desc *desc, *_desc;
	struct fsl_re_hw_desc *hwdesc;
	unsigned long flags;
	unsigned int count, oub_count;
	int found;

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

	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 = efrl;
	cf[index].addr_high = upper_32_bits(addr);
	cf[index].addr_low = 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 = FSL_RE_FRAME_FORMAT << FSL_RE_HWDESC_FMT_SHIFT;
	desc->hwdesc.lbea32 = upper_32_bits(paddr);
	desc->hwdesc.addr_low = 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(sizeof(*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);

	if (cont_q)
		fill_cfd_frame(cf, i++, len, dest, 0);

	/* Setting the final bit in the last source buffer frame in CFD */
	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;

	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], 0);
		} else {
			dev_err(re_chan->dev, "PQ tx continuation error!\n");
			return NULL;
		}
	}

	/* Setting the final bit in the last source buffer frame in CFD */
	cf[i - 1].efrl32 |= 1 << FSL_RE_CF_FINAL_SHIFT;

	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(sizeof(*desc), GFP_KERNEL);
		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 = (struct fsl_re_chan_cfg *)((u8 *)re_priv->re_regs +
			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_init(&chan->irqtask, fsl_re_dequeue, (unsigned long)chandev);

	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_drv_private *re_priv;
	struct device_node *np;
	struct device_node *child;
	u32 off;
	u8 ridx = 0;
	struct dma_device *dma_dev;
	struct resource *res;
	int rc;
	struct device *dev = &ofdev->dev;

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

	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	/* IOMAP the entire RAID Engine region */
	re_priv->re_regs = devm_ioremap(dev, res->start, resource_size(res));
	if (!re_priv->re_regs)
		return -EBUSY;

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

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

	dev_info(dev, "version %x, mode %x, gfp %x\n",
		 in_be32(&re_priv->re_regs->re_version_id),
		 in_be32(&re_priv->re_regs->global_config),
		 in_be32(&re_priv->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(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");
			of_node_put(np);
			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 int 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);

	return 0;
}

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");
