/*
 * timb_dma.c timberdale FPGA DMA driver
 * Copyright (c) 2010 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Supports:
 * Timberdale FPGA DMA engine
 */

#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <linux/timb_dma.h>

#define DRIVER_NAME "timb-dma"

/* Global DMA registers */
#define TIMBDMA_ACR		0x34
#define TIMBDMA_32BIT_ADDR	0x01

#define TIMBDMA_ISR		0x080000
#define TIMBDMA_IPR		0x080004
#define TIMBDMA_IER		0x080008

/* Channel specific registers */
/* RX instances base addresses are 0x00, 0x40, 0x80 ...
 * TX instances base addresses are 0x18, 0x58, 0x98 ...
 */
#define TIMBDMA_INSTANCE_OFFSET		0x40
#define TIMBDMA_INSTANCE_TX_OFFSET	0x18

/* RX registers, relative the instance base */
#define TIMBDMA_OFFS_RX_DHAR	0x00
#define TIMBDMA_OFFS_RX_DLAR	0x04
#define TIMBDMA_OFFS_RX_LR	0x0C
#define TIMBDMA_OFFS_RX_BLR	0x10
#define TIMBDMA_OFFS_RX_ER	0x14
#define TIMBDMA_RX_EN		0x01
/* bytes per Row, video specific register
 * which is placed after the TX registers...
 */
#define TIMBDMA_OFFS_RX_BPRR	0x30

/* TX registers, relative the instance base */
#define TIMBDMA_OFFS_TX_DHAR	0x00
#define TIMBDMA_OFFS_TX_DLAR	0x04
#define TIMBDMA_OFFS_TX_BLR	0x0C
#define TIMBDMA_OFFS_TX_LR	0x14


#define TIMB_DMA_DESC_SIZE	8

struct timb_dma_desc {
	struct list_head		desc_node;
	struct dma_async_tx_descriptor	txd;
	u8				*desc_list;
	unsigned int			desc_list_len;
	bool				interrupt;
};

struct timb_dma_chan {
	struct dma_chan		chan;
	void __iomem		*membase;
	spinlock_t		lock; /* Used to protect data structures,
					especially the lists and descriptors,
					from races between the tasklet and calls
					from above */
	dma_cookie_t		last_completed_cookie;
	bool			ongoing;
	struct list_head	active_list;
	struct list_head	queue;
	struct list_head	free_list;
	unsigned int		bytes_per_line;
	enum dma_transfer_direction	direction;
	unsigned int		descs; /* Descriptors to allocate */
	unsigned int		desc_elems; /* number of elems per descriptor */
};

struct timb_dma {
	struct dma_device	dma;
	void __iomem		*membase;
	struct tasklet_struct	tasklet;
	struct timb_dma_chan	channels[0];
};

static struct device *chan2dev(struct dma_chan *chan)
{
	return &chan->dev->device;
}
static struct device *chan2dmadev(struct dma_chan *chan)
{
	return chan2dev(chan)->parent->parent;
}

static struct timb_dma *tdchantotd(struct timb_dma_chan *td_chan)
{
	int id = td_chan->chan.chan_id;
	return (struct timb_dma *)((u8 *)td_chan -
		id * sizeof(struct timb_dma_chan) - sizeof(struct timb_dma));
}

/* Must be called with the spinlock held */
static void __td_enable_chan_irq(struct timb_dma_chan *td_chan)
{
	int id = td_chan->chan.chan_id;
	struct timb_dma *td = tdchantotd(td_chan);
	u32 ier;

	/* enable interrupt for this channel */
	ier = ioread32(td->membase + TIMBDMA_IER);
	ier |= 1 << id;
	dev_dbg(chan2dev(&td_chan->chan), "Enabling irq: %d, IER: 0x%x\n", id,
		ier);
	iowrite32(ier, td->membase + TIMBDMA_IER);
}

/* Should be called with the spinlock held */
static bool __td_dma_done_ack(struct timb_dma_chan *td_chan)
{
	int id = td_chan->chan.chan_id;
	struct timb_dma *td = (struct timb_dma *)((u8 *)td_chan -
		id * sizeof(struct timb_dma_chan) - sizeof(struct timb_dma));
	u32 isr;
	bool done = false;

	dev_dbg(chan2dev(&td_chan->chan), "Checking irq: %d, td: %p\n", id, td);

	isr = ioread32(td->membase + TIMBDMA_ISR) & (1 << id);
	if (isr) {
		iowrite32(isr, td->membase + TIMBDMA_ISR);
		done = true;
	}

	return done;
}

static void __td_unmap_desc(struct timb_dma_chan *td_chan, const u8 *dma_desc,
	bool single)
{
	dma_addr_t addr;
	int len;

	addr = (dma_desc[7] << 24) | (dma_desc[6] << 16) | (dma_desc[5] << 8) |
		dma_desc[4];

	len = (dma_desc[3] << 8) | dma_desc[2];

	if (single)
		dma_unmap_single(chan2dev(&td_chan->chan), addr, len,
			DMA_TO_DEVICE);
	else
		dma_unmap_page(chan2dev(&td_chan->chan), addr, len,
			DMA_TO_DEVICE);
}

static void __td_unmap_descs(struct timb_dma_desc *td_desc, bool single)
{
	struct timb_dma_chan *td_chan = container_of(td_desc->txd.chan,
		struct timb_dma_chan, chan);
	u8 *descs;

	for (descs = td_desc->desc_list; ; descs += TIMB_DMA_DESC_SIZE) {
		__td_unmap_desc(td_chan, descs, single);
		if (descs[0] & 0x02)
			break;
	}
}

static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc,
	struct scatterlist *sg, bool last)
{
	if (sg_dma_len(sg) > USHRT_MAX) {
		dev_err(chan2dev(&td_chan->chan), "Too big sg element\n");
		return -EINVAL;
	}

	/* length must be word aligned */
	if (sg_dma_len(sg) % sizeof(u32)) {
		dev_err(chan2dev(&td_chan->chan), "Incorrect length: %d\n",
			sg_dma_len(sg));
		return -EINVAL;
	}

	dev_dbg(chan2dev(&td_chan->chan), "desc: %p, addr: 0x%llx\n",
		dma_desc, (unsigned long long)sg_dma_address(sg));

	dma_desc[7] = (sg_dma_address(sg) >> 24) & 0xff;
	dma_desc[6] = (sg_dma_address(sg) >> 16) & 0xff;
	dma_desc[5] = (sg_dma_address(sg) >> 8) & 0xff;
	dma_desc[4] = (sg_dma_address(sg) >> 0) & 0xff;

	dma_desc[3] = (sg_dma_len(sg) >> 8) & 0xff;
	dma_desc[2] = (sg_dma_len(sg) >> 0) & 0xff;

	dma_desc[1] = 0x00;
	dma_desc[0] = 0x21 | (last ? 0x02 : 0); /* tran, valid */

	return 0;
}

/* Must be called with the spinlock held */
static void __td_start_dma(struct timb_dma_chan *td_chan)
{
	struct timb_dma_desc *td_desc;

	if (td_chan->ongoing) {
		dev_err(chan2dev(&td_chan->chan),
			"Transfer already ongoing\n");
		return;
	}

	td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc,
		desc_node);

	dev_dbg(chan2dev(&td_chan->chan),
		"td_chan: %p, chan: %d, membase: %p\n",
		td_chan, td_chan->chan.chan_id, td_chan->membase);

	if (td_chan->direction == DMA_DEV_TO_MEM) {

		/* descriptor address */
		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_RX_DHAR);
		iowrite32(td_desc->txd.phys, td_chan->membase +
			TIMBDMA_OFFS_RX_DLAR);
		/* Bytes per line */
		iowrite32(td_chan->bytes_per_line, td_chan->membase +
			TIMBDMA_OFFS_RX_BPRR);
		/* enable RX */
		iowrite32(TIMBDMA_RX_EN, td_chan->membase + TIMBDMA_OFFS_RX_ER);
	} else {
		/* address high */
		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DHAR);
		iowrite32(td_desc->txd.phys, td_chan->membase +
			TIMBDMA_OFFS_TX_DLAR);
	}

	td_chan->ongoing = true;

	if (td_desc->interrupt)
		__td_enable_chan_irq(td_chan);
}

static void __td_finish(struct timb_dma_chan *td_chan)
{
	dma_async_tx_callback		callback;
	void				*param;
	struct dma_async_tx_descriptor	*txd;
	struct timb_dma_desc		*td_desc;

	/* can happen if the descriptor is canceled */
	if (list_empty(&td_chan->active_list))
		return;

	td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc,
		desc_node);
	txd = &td_desc->txd;

	dev_dbg(chan2dev(&td_chan->chan), "descriptor %u complete\n",
		txd->cookie);

	/* make sure to stop the transfer */
	if (td_chan->direction == DMA_DEV_TO_MEM)
		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_RX_ER);
/* Currently no support for stopping DMA transfers
	else
		iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR);
*/
	td_chan->last_completed_cookie = txd->cookie;
	td_chan->ongoing = false;

	callback = txd->callback;
	param = txd->callback_param;

	list_move(&td_desc->desc_node, &td_chan->free_list);

	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP))
		__td_unmap_descs(td_desc,
			txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE);

	/*
	 * The API requires that no submissions are done from a
	 * callback, so we don't need to drop the lock here
	 */
	if (callback)
		callback(param);
}

static u32 __td_ier_mask(struct timb_dma *td)
{
	int i;
	u32 ret = 0;

	for (i = 0; i < td->dma.chancnt; i++) {
		struct timb_dma_chan *td_chan = td->channels + i;
		if (td_chan->ongoing) {
			struct timb_dma_desc *td_desc =
				list_entry(td_chan->active_list.next,
				struct timb_dma_desc, desc_node);
			if (td_desc->interrupt)
				ret |= 1 << i;
		}
	}

	return ret;
}

static void __td_start_next(struct timb_dma_chan *td_chan)
{
	struct timb_dma_desc *td_desc;

	BUG_ON(list_empty(&td_chan->queue));
	BUG_ON(td_chan->ongoing);

	td_desc = list_entry(td_chan->queue.next, struct timb_dma_desc,
		desc_node);

	dev_dbg(chan2dev(&td_chan->chan), "%s: started %u\n",
		__func__, td_desc->txd.cookie);

	list_move(&td_desc->desc_node, &td_chan->active_list);
	__td_start_dma(td_chan);
}

static dma_cookie_t td_tx_submit(struct dma_async_tx_descriptor *txd)
{
	struct timb_dma_desc *td_desc = container_of(txd, struct timb_dma_desc,
		txd);
	struct timb_dma_chan *td_chan = container_of(txd->chan,
		struct timb_dma_chan, chan);
	dma_cookie_t cookie;

	spin_lock_bh(&td_chan->lock);

	cookie = txd->chan->cookie;
	if (++cookie < 0)
		cookie = 1;
	txd->chan->cookie = cookie;
	txd->cookie = cookie;

	if (list_empty(&td_chan->active_list)) {
		dev_dbg(chan2dev(txd->chan), "%s: started %u\n", __func__,
			txd->cookie);
		list_add_tail(&td_desc->desc_node, &td_chan->active_list);
		__td_start_dma(td_chan);
	} else {
		dev_dbg(chan2dev(txd->chan), "tx_submit: queued %u\n",
			txd->cookie);

		list_add_tail(&td_desc->desc_node, &td_chan->queue);
	}

	spin_unlock_bh(&td_chan->lock);

	return cookie;
}

static struct timb_dma_desc *td_alloc_init_desc(struct timb_dma_chan *td_chan)
{
	struct dma_chan *chan = &td_chan->chan;
	struct timb_dma_desc *td_desc;
	int err;

	td_desc = kzalloc(sizeof(struct timb_dma_desc), GFP_KERNEL);
	if (!td_desc) {
		dev_err(chan2dev(chan), "Failed to alloc descriptor\n");
		goto out;
	}

	td_desc->desc_list_len = td_chan->desc_elems * TIMB_DMA_DESC_SIZE;

	td_desc->desc_list = kzalloc(td_desc->desc_list_len, GFP_KERNEL);
	if (!td_desc->desc_list) {
		dev_err(chan2dev(chan), "Failed to alloc descriptor\n");
		goto err;
	}

	dma_async_tx_descriptor_init(&td_desc->txd, chan);
	td_desc->txd.tx_submit = td_tx_submit;
	td_desc->txd.flags = DMA_CTRL_ACK;

	td_desc->txd.phys = dma_map_single(chan2dmadev(chan),
		td_desc->desc_list, td_desc->desc_list_len, DMA_TO_DEVICE);

	err = dma_mapping_error(chan2dmadev(chan), td_desc->txd.phys);
	if (err) {
		dev_err(chan2dev(chan), "DMA mapping error: %d\n", err);
		goto err;
	}

	return td_desc;
err:
	kfree(td_desc->desc_list);
	kfree(td_desc);
out:
	return NULL;

}

static void td_free_desc(struct timb_dma_desc *td_desc)
{
	dev_dbg(chan2dev(td_desc->txd.chan), "Freeing desc: %p\n", td_desc);
	dma_unmap_single(chan2dmadev(td_desc->txd.chan), td_desc->txd.phys,
		td_desc->desc_list_len, DMA_TO_DEVICE);

	kfree(td_desc->desc_list);
	kfree(td_desc);
}

static void td_desc_put(struct timb_dma_chan *td_chan,
	struct timb_dma_desc *td_desc)
{
	dev_dbg(chan2dev(&td_chan->chan), "Putting desc: %p\n", td_desc);

	spin_lock_bh(&td_chan->lock);
	list_add(&td_desc->desc_node, &td_chan->free_list);
	spin_unlock_bh(&td_chan->lock);
}

static struct timb_dma_desc *td_desc_get(struct timb_dma_chan *td_chan)
{
	struct timb_dma_desc *td_desc, *_td_desc;
	struct timb_dma_desc *ret = NULL;

	spin_lock_bh(&td_chan->lock);
	list_for_each_entry_safe(td_desc, _td_desc, &td_chan->free_list,
		desc_node) {
		if (async_tx_test_ack(&td_desc->txd)) {
			list_del(&td_desc->desc_node);
			ret = td_desc;
			break;
		}
		dev_dbg(chan2dev(&td_chan->chan), "desc %p not ACKed\n",
			td_desc);
	}
	spin_unlock_bh(&td_chan->lock);

	return ret;
}

static int td_alloc_chan_resources(struct dma_chan *chan)
{
	struct timb_dma_chan *td_chan =
		container_of(chan, struct timb_dma_chan, chan);
	int i;

	dev_dbg(chan2dev(chan), "%s: entry\n", __func__);

	BUG_ON(!list_empty(&td_chan->free_list));
	for (i = 0; i < td_chan->descs; i++) {
		struct timb_dma_desc *td_desc = td_alloc_init_desc(td_chan);
		if (!td_desc) {
			if (i)
				break;
			else {
				dev_err(chan2dev(chan),
					"Couldnt allocate any descriptors\n");
				return -ENOMEM;
			}
		}

		td_desc_put(td_chan, td_desc);
	}

	spin_lock_bh(&td_chan->lock);
	td_chan->last_completed_cookie = 1;
	chan->cookie = 1;
	spin_unlock_bh(&td_chan->lock);

	return 0;
}

static void td_free_chan_resources(struct dma_chan *chan)
{
	struct timb_dma_chan *td_chan =
		container_of(chan, struct timb_dma_chan, chan);
	struct timb_dma_desc *td_desc, *_td_desc;
	LIST_HEAD(list);

	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);

	/* check that all descriptors are free */
	BUG_ON(!list_empty(&td_chan->active_list));
	BUG_ON(!list_empty(&td_chan->queue));

	spin_lock_bh(&td_chan->lock);
	list_splice_init(&td_chan->free_list, &list);
	spin_unlock_bh(&td_chan->lock);

	list_for_each_entry_safe(td_desc, _td_desc, &list, desc_node) {
		dev_dbg(chan2dev(chan), "%s: Freeing desc: %p\n", __func__,
			td_desc);
		td_free_desc(td_desc);
	}
}

static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
				    struct dma_tx_state *txstate)
{
	struct timb_dma_chan *td_chan =
		container_of(chan, struct timb_dma_chan, chan);
	dma_cookie_t		last_used;
	dma_cookie_t		last_complete;
	int			ret;

	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);

	last_complete = td_chan->last_completed_cookie;
	last_used = chan->cookie;

	ret = dma_async_is_complete(cookie, last_complete, last_used);

	dma_set_tx_state(txstate, last_complete, last_used, 0);

	dev_dbg(chan2dev(chan),
		"%s: exit, ret: %d, last_complete: %d, last_used: %d\n",
		__func__, ret, last_complete, last_used);

	return ret;
}

static void td_issue_pending(struct dma_chan *chan)
{
	struct timb_dma_chan *td_chan =
		container_of(chan, struct timb_dma_chan, chan);

	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);
	spin_lock_bh(&td_chan->lock);

	if (!list_empty(&td_chan->active_list))
		/* transfer ongoing */
		if (__td_dma_done_ack(td_chan))
			__td_finish(td_chan);

	if (list_empty(&td_chan->active_list) && !list_empty(&td_chan->queue))
		__td_start_next(td_chan);

	spin_unlock_bh(&td_chan->lock);
}

static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan,
	struct scatterlist *sgl, unsigned int sg_len,
	enum dma_transfer_direction direction, unsigned long flags)
{
	struct timb_dma_chan *td_chan =
		container_of(chan, struct timb_dma_chan, chan);
	struct timb_dma_desc *td_desc;
	struct scatterlist *sg;
	unsigned int i;
	unsigned int desc_usage = 0;

	if (!sgl || !sg_len) {
		dev_err(chan2dev(chan), "%s: No SG list\n", __func__);
		return NULL;
	}

	/* even channels are for RX, odd for TX */
	if (td_chan->direction != direction) {
		dev_err(chan2dev(chan),
			"Requesting channel in wrong direction\n");
		return NULL;
	}

	td_desc = td_desc_get(td_chan);
	if (!td_desc) {
		dev_err(chan2dev(chan), "Not enough descriptors available\n");
		return NULL;
	}

	td_desc->interrupt = (flags & DMA_PREP_INTERRUPT) != 0;

	for_each_sg(sgl, sg, sg_len, i) {
		int err;
		if (desc_usage > td_desc->desc_list_len) {
			dev_err(chan2dev(chan), "No descriptor space\n");
			return NULL;
		}

		err = td_fill_desc(td_chan, td_desc->desc_list + desc_usage, sg,
			i == (sg_len - 1));
		if (err) {
			dev_err(chan2dev(chan), "Failed to update desc: %d\n",
				err);
			td_desc_put(td_chan, td_desc);
			return NULL;
		}
		desc_usage += TIMB_DMA_DESC_SIZE;
	}

	dma_sync_single_for_device(chan2dmadev(chan), td_desc->txd.phys,
		td_desc->desc_list_len, DMA_MEM_TO_DEV);

	return &td_desc->txd;
}

static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
		      unsigned long arg)
{
	struct timb_dma_chan *td_chan =
		container_of(chan, struct timb_dma_chan, chan);
	struct timb_dma_desc *td_desc, *_td_desc;

	dev_dbg(chan2dev(chan), "%s: Entry\n", __func__);

	if (cmd != DMA_TERMINATE_ALL)
		return -ENXIO;

	/* first the easy part, put the queue into the free list */
	spin_lock_bh(&td_chan->lock);
	list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue,
		desc_node)
		list_move(&td_desc->desc_node, &td_chan->free_list);

	/* now tear down the running */
	__td_finish(td_chan);
	spin_unlock_bh(&td_chan->lock);

	return 0;
}

static void td_tasklet(unsigned long data)
{
	struct timb_dma *td = (struct timb_dma *)data;
	u32 isr;
	u32 ipr;
	u32 ier;
	int i;

	isr = ioread32(td->membase + TIMBDMA_ISR);
	ipr = isr & __td_ier_mask(td);

	/* ack the interrupts */
	iowrite32(ipr, td->membase + TIMBDMA_ISR);

	for (i = 0; i < td->dma.chancnt; i++)
		if (ipr & (1 << i)) {
			struct timb_dma_chan *td_chan = td->channels + i;
			spin_lock(&td_chan->lock);
			__td_finish(td_chan);
			if (!list_empty(&td_chan->queue))
				__td_start_next(td_chan);
			spin_unlock(&td_chan->lock);
		}

	ier = __td_ier_mask(td);
	iowrite32(ier, td->membase + TIMBDMA_IER);
}


static irqreturn_t td_irq(int irq, void *devid)
{
	struct timb_dma *td = devid;
	u32 ipr = ioread32(td->membase + TIMBDMA_IPR);

	if (ipr) {
		/* disable interrupts, will be re-enabled in tasklet */
		iowrite32(0, td->membase + TIMBDMA_IER);

		tasklet_schedule(&td->tasklet);

		return IRQ_HANDLED;
	} else
		return IRQ_NONE;
}


static int __devinit td_probe(struct platform_device *pdev)
{
	struct timb_dma_platform_data *pdata = pdev->dev.platform_data;
	struct timb_dma *td;
	struct resource *iomem;
	int irq;
	int err;
	int i;

	if (!pdata) {
		dev_err(&pdev->dev, "No platform data\n");
		return -EINVAL;
	}

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iomem)
		return -EINVAL;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	if (!request_mem_region(iomem->start, resource_size(iomem),
		DRIVER_NAME))
		return -EBUSY;

	td  = kzalloc(sizeof(struct timb_dma) +
		sizeof(struct timb_dma_chan) * pdata->nr_channels, GFP_KERNEL);
	if (!td) {
		err = -ENOMEM;
		goto err_release_region;
	}

	dev_dbg(&pdev->dev, "Allocated TD: %p\n", td);

	td->membase = ioremap(iomem->start, resource_size(iomem));
	if (!td->membase) {
		dev_err(&pdev->dev, "Failed to remap I/O memory\n");
		err = -ENOMEM;
		goto err_free_mem;
	}

	/* 32bit addressing */
	iowrite32(TIMBDMA_32BIT_ADDR, td->membase + TIMBDMA_ACR);

	/* disable and clear any interrupts */
	iowrite32(0x0, td->membase + TIMBDMA_IER);
	iowrite32(0xFFFFFFFF, td->membase + TIMBDMA_ISR);

	tasklet_init(&td->tasklet, td_tasklet, (unsigned long)td);

	err = request_irq(irq, td_irq, IRQF_SHARED, DRIVER_NAME, td);
	if (err) {
		dev_err(&pdev->dev, "Failed to request IRQ\n");
		goto err_tasklet_kill;
	}

	td->dma.device_alloc_chan_resources	= td_alloc_chan_resources;
	td->dma.device_free_chan_resources	= td_free_chan_resources;
	td->dma.device_tx_status		= td_tx_status;
	td->dma.device_issue_pending		= td_issue_pending;

	dma_cap_set(DMA_SLAVE, td->dma.cap_mask);
	dma_cap_set(DMA_PRIVATE, td->dma.cap_mask);
	td->dma.device_prep_slave_sg = td_prep_slave_sg;
	td->dma.device_control = td_control;

	td->dma.dev = &pdev->dev;

	INIT_LIST_HEAD(&td->dma.channels);

	for (i = 0; i < pdata->nr_channels; i++) {
		struct timb_dma_chan *td_chan = &td->channels[i];
		struct timb_dma_platform_data_channel *pchan =
			pdata->channels + i;

		/* even channels are RX, odd are TX */
		if ((i % 2) == pchan->rx) {
			dev_err(&pdev->dev, "Wrong channel configuration\n");
			err = -EINVAL;
			goto err_free_irq;
		}

		td_chan->chan.device = &td->dma;
		td_chan->chan.cookie = 1;
		spin_lock_init(&td_chan->lock);
		INIT_LIST_HEAD(&td_chan->active_list);
		INIT_LIST_HEAD(&td_chan->queue);
		INIT_LIST_HEAD(&td_chan->free_list);

		td_chan->descs = pchan->descriptors;
		td_chan->desc_elems = pchan->descriptor_elements;
		td_chan->bytes_per_line = pchan->bytes_per_line;
		td_chan->direction = pchan->rx ? DMA_DEV_TO_MEM :
			DMA_MEM_TO_DEV;

		td_chan->membase = td->membase +
			(i / 2) * TIMBDMA_INSTANCE_OFFSET +
			(pchan->rx ? 0 : TIMBDMA_INSTANCE_TX_OFFSET);

		dev_dbg(&pdev->dev, "Chan: %d, membase: %p\n",
			i, td_chan->membase);

		list_add_tail(&td_chan->chan.device_node, &td->dma.channels);
	}

	err = dma_async_device_register(&td->dma);
	if (err) {
		dev_err(&pdev->dev, "Failed to register async device\n");
		goto err_free_irq;
	}

	platform_set_drvdata(pdev, td);

	dev_dbg(&pdev->dev, "Probe result: %d\n", err);
	return err;

err_free_irq:
	free_irq(irq, td);
err_tasklet_kill:
	tasklet_kill(&td->tasklet);
	iounmap(td->membase);
err_free_mem:
	kfree(td);
err_release_region:
	release_mem_region(iomem->start, resource_size(iomem));

	return err;

}

static int __devexit td_remove(struct platform_device *pdev)
{
	struct timb_dma *td = platform_get_drvdata(pdev);
	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	int irq = platform_get_irq(pdev, 0);

	dma_async_device_unregister(&td->dma);
	free_irq(irq, td);
	tasklet_kill(&td->tasklet);
	iounmap(td->membase);
	kfree(td);
	release_mem_region(iomem->start, resource_size(iomem));

	platform_set_drvdata(pdev, NULL);

	dev_dbg(&pdev->dev, "Removed...\n");
	return 0;
}

static struct platform_driver td_driver = {
	.driver = {
		.name	= DRIVER_NAME,
		.owner  = THIS_MODULE,
	},
	.probe	= td_probe,
	.remove	= __exit_p(td_remove),
};

module_platform_driver(td_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Timberdale DMA controller driver");
MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>");
MODULE_ALIAS("platform:"DRIVER_NAME);
