/*
 * OMAP DMAengine support
 *
 * 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.
 */
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/omap-dma.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/of_dma.h>
#include <linux/of_device.h>

#include "virt-dma.h"

#define OMAP_SDMA_REQUESTS	127
#define OMAP_SDMA_CHANNELS	32

struct omap_dmadev {
	struct dma_device ddev;
	spinlock_t lock;
	void __iomem *base;
	const struct omap_dma_reg *reg_map;
	struct omap_system_dma_plat_info *plat;
	bool legacy;
	bool ll123_supported;
	struct dma_pool *desc_pool;
	unsigned dma_requests;
	spinlock_t irq_lock;
	uint32_t irq_enable_mask;
	struct omap_chan **lch_map;
};

struct omap_chan {
	struct virt_dma_chan vc;
	void __iomem *channel_base;
	const struct omap_dma_reg *reg_map;
	uint32_t ccr;

	struct dma_slave_config	cfg;
	unsigned dma_sig;
	bool cyclic;
	bool paused;
	bool running;

	int dma_ch;
	struct omap_desc *desc;
	unsigned sgidx;
};

#define DESC_NXT_SV_REFRESH	(0x1 << 24)
#define DESC_NXT_SV_REUSE	(0x2 << 24)
#define DESC_NXT_DV_REFRESH	(0x1 << 26)
#define DESC_NXT_DV_REUSE	(0x2 << 26)
#define DESC_NTYPE_TYPE2	(0x2 << 29)

/* Type 2 descriptor with Source or Destination address update */
struct omap_type2_desc {
	uint32_t next_desc;
	uint32_t en;
	uint32_t addr; /* src or dst */
	uint16_t fn;
	uint16_t cicr;
	int16_t cdei;
	int16_t csei;
	int32_t cdfi;
	int32_t csfi;
} __packed;

struct omap_sg {
	dma_addr_t addr;
	uint32_t en;		/* number of elements (24-bit) */
	uint32_t fn;		/* number of frames (16-bit) */
	int32_t fi;		/* for double indexing */
	int16_t ei;		/* for double indexing */

	/* Linked list */
	struct omap_type2_desc *t2_desc;
	dma_addr_t t2_desc_paddr;
};

struct omap_desc {
	struct virt_dma_desc vd;
	bool using_ll;
	enum dma_transfer_direction dir;
	dma_addr_t dev_addr;

	int32_t fi;		/* for OMAP_DMA_SYNC_PACKET / double indexing */
	int16_t ei;		/* for double indexing */
	uint8_t es;		/* CSDP_DATA_TYPE_xxx */
	uint32_t ccr;		/* CCR value */
	uint16_t clnk_ctrl;	/* CLNK_CTRL value */
	uint16_t cicr;		/* CICR value */
	uint32_t csdp;		/* CSDP value */

	unsigned sglen;
	struct omap_sg sg[0];
};

enum {
	CAPS_0_SUPPORT_LL123	= BIT(20),	/* Linked List type1/2/3 */
	CAPS_0_SUPPORT_LL4	= BIT(21),	/* Linked List type4 */

	CCR_FS			= BIT(5),
	CCR_READ_PRIORITY	= BIT(6),
	CCR_ENABLE		= BIT(7),
	CCR_AUTO_INIT		= BIT(8),	/* OMAP1 only */
	CCR_REPEAT		= BIT(9),	/* OMAP1 only */
	CCR_OMAP31_DISABLE	= BIT(10),	/* OMAP1 only */
	CCR_SUSPEND_SENSITIVE	= BIT(8),	/* OMAP2+ only */
	CCR_RD_ACTIVE		= BIT(9),	/* OMAP2+ only */
	CCR_WR_ACTIVE		= BIT(10),	/* OMAP2+ only */
	CCR_SRC_AMODE_CONSTANT	= 0 << 12,
	CCR_SRC_AMODE_POSTINC	= 1 << 12,
	CCR_SRC_AMODE_SGLIDX	= 2 << 12,
	CCR_SRC_AMODE_DBLIDX	= 3 << 12,
	CCR_DST_AMODE_CONSTANT	= 0 << 14,
	CCR_DST_AMODE_POSTINC	= 1 << 14,
	CCR_DST_AMODE_SGLIDX	= 2 << 14,
	CCR_DST_AMODE_DBLIDX	= 3 << 14,
	CCR_CONSTANT_FILL	= BIT(16),
	CCR_TRANSPARENT_COPY	= BIT(17),
	CCR_BS			= BIT(18),
	CCR_SUPERVISOR		= BIT(22),
	CCR_PREFETCH		= BIT(23),
	CCR_TRIGGER_SRC		= BIT(24),
	CCR_BUFFERING_DISABLE	= BIT(25),
	CCR_WRITE_PRIORITY	= BIT(26),
	CCR_SYNC_ELEMENT	= 0,
	CCR_SYNC_FRAME		= CCR_FS,
	CCR_SYNC_BLOCK		= CCR_BS,
	CCR_SYNC_PACKET		= CCR_BS | CCR_FS,

	CSDP_DATA_TYPE_8	= 0,
	CSDP_DATA_TYPE_16	= 1,
	CSDP_DATA_TYPE_32	= 2,
	CSDP_SRC_PORT_EMIFF	= 0 << 2, /* OMAP1 only */
	CSDP_SRC_PORT_EMIFS	= 1 << 2, /* OMAP1 only */
	CSDP_SRC_PORT_OCP_T1	= 2 << 2, /* OMAP1 only */
	CSDP_SRC_PORT_TIPB	= 3 << 2, /* OMAP1 only */
	CSDP_SRC_PORT_OCP_T2	= 4 << 2, /* OMAP1 only */
	CSDP_SRC_PORT_MPUI	= 5 << 2, /* OMAP1 only */
	CSDP_SRC_PACKED		= BIT(6),
	CSDP_SRC_BURST_1	= 0 << 7,
	CSDP_SRC_BURST_16	= 1 << 7,
	CSDP_SRC_BURST_32	= 2 << 7,
	CSDP_SRC_BURST_64	= 3 << 7,
	CSDP_DST_PORT_EMIFF	= 0 << 9, /* OMAP1 only */
	CSDP_DST_PORT_EMIFS	= 1 << 9, /* OMAP1 only */
	CSDP_DST_PORT_OCP_T1	= 2 << 9, /* OMAP1 only */
	CSDP_DST_PORT_TIPB	= 3 << 9, /* OMAP1 only */
	CSDP_DST_PORT_OCP_T2	= 4 << 9, /* OMAP1 only */
	CSDP_DST_PORT_MPUI	= 5 << 9, /* OMAP1 only */
	CSDP_DST_PACKED		= BIT(13),
	CSDP_DST_BURST_1	= 0 << 14,
	CSDP_DST_BURST_16	= 1 << 14,
	CSDP_DST_BURST_32	= 2 << 14,
	CSDP_DST_BURST_64	= 3 << 14,
	CSDP_WRITE_NON_POSTED	= 0 << 16,
	CSDP_WRITE_POSTED	= 1 << 16,
	CSDP_WRITE_LAST_NON_POSTED = 2 << 16,

	CICR_TOUT_IE		= BIT(0),	/* OMAP1 only */
	CICR_DROP_IE		= BIT(1),
	CICR_HALF_IE		= BIT(2),
	CICR_FRAME_IE		= BIT(3),
	CICR_LAST_IE		= BIT(4),
	CICR_BLOCK_IE		= BIT(5),
	CICR_PKT_IE		= BIT(7),	/* OMAP2+ only */
	CICR_TRANS_ERR_IE	= BIT(8),	/* OMAP2+ only */
	CICR_SUPERVISOR_ERR_IE	= BIT(10),	/* OMAP2+ only */
	CICR_MISALIGNED_ERR_IE	= BIT(11),	/* OMAP2+ only */
	CICR_DRAIN_IE		= BIT(12),	/* OMAP2+ only */
	CICR_SUPER_BLOCK_IE	= BIT(14),	/* OMAP2+ only */

	CLNK_CTRL_ENABLE_LNK	= BIT(15),

	CDP_DST_VALID_INC	= 0 << 0,
	CDP_DST_VALID_RELOAD	= 1 << 0,
	CDP_DST_VALID_REUSE	= 2 << 0,
	CDP_SRC_VALID_INC	= 0 << 2,
	CDP_SRC_VALID_RELOAD	= 1 << 2,
	CDP_SRC_VALID_REUSE	= 2 << 2,
	CDP_NTYPE_TYPE1		= 1 << 4,
	CDP_NTYPE_TYPE2		= 2 << 4,
	CDP_NTYPE_TYPE3		= 3 << 4,
	CDP_TMODE_NORMAL	= 0 << 8,
	CDP_TMODE_LLIST		= 1 << 8,
	CDP_FAST		= BIT(10),
};

static const unsigned es_bytes[] = {
	[CSDP_DATA_TYPE_8] = 1,
	[CSDP_DATA_TYPE_16] = 2,
	[CSDP_DATA_TYPE_32] = 4,
};

static struct of_dma_filter_info omap_dma_info = {
	.filter_fn = omap_dma_filter_fn,
};

static inline struct omap_dmadev *to_omap_dma_dev(struct dma_device *d)
{
	return container_of(d, struct omap_dmadev, ddev);
}

static inline struct omap_chan *to_omap_dma_chan(struct dma_chan *c)
{
	return container_of(c, struct omap_chan, vc.chan);
}

static inline struct omap_desc *to_omap_dma_desc(struct dma_async_tx_descriptor *t)
{
	return container_of(t, struct omap_desc, vd.tx);
}

static void omap_dma_desc_free(struct virt_dma_desc *vd)
{
	struct omap_desc *d = to_omap_dma_desc(&vd->tx);

	if (d->using_ll) {
		struct omap_dmadev *od = to_omap_dma_dev(vd->tx.chan->device);
		int i;

		for (i = 0; i < d->sglen; i++) {
			if (d->sg[i].t2_desc)
				dma_pool_free(od->desc_pool, d->sg[i].t2_desc,
					      d->sg[i].t2_desc_paddr);
		}
	}

	kfree(d);
}

static void omap_dma_fill_type2_desc(struct omap_desc *d, int idx,
				     enum dma_transfer_direction dir, bool last)
{
	struct omap_sg *sg = &d->sg[idx];
	struct omap_type2_desc *t2_desc = sg->t2_desc;

	if (idx)
		d->sg[idx - 1].t2_desc->next_desc = sg->t2_desc_paddr;
	if (last)
		t2_desc->next_desc = 0xfffffffc;

	t2_desc->en = sg->en;
	t2_desc->addr = sg->addr;
	t2_desc->fn = sg->fn & 0xffff;
	t2_desc->cicr = d->cicr;
	if (!last)
		t2_desc->cicr &= ~CICR_BLOCK_IE;

	switch (dir) {
	case DMA_DEV_TO_MEM:
		t2_desc->cdei = sg->ei;
		t2_desc->csei = d->ei;
		t2_desc->cdfi = sg->fi;
		t2_desc->csfi = d->fi;

		t2_desc->en |= DESC_NXT_DV_REFRESH;
		t2_desc->en |= DESC_NXT_SV_REUSE;
		break;
	case DMA_MEM_TO_DEV:
		t2_desc->cdei = d->ei;
		t2_desc->csei = sg->ei;
		t2_desc->cdfi = d->fi;
		t2_desc->csfi = sg->fi;

		t2_desc->en |= DESC_NXT_SV_REFRESH;
		t2_desc->en |= DESC_NXT_DV_REUSE;
		break;
	default:
		return;
	}

	t2_desc->en |= DESC_NTYPE_TYPE2;
}

static void omap_dma_write(uint32_t val, unsigned type, void __iomem *addr)
{
	switch (type) {
	case OMAP_DMA_REG_16BIT:
		writew_relaxed(val, addr);
		break;
	case OMAP_DMA_REG_2X16BIT:
		writew_relaxed(val, addr);
		writew_relaxed(val >> 16, addr + 2);
		break;
	case OMAP_DMA_REG_32BIT:
		writel_relaxed(val, addr);
		break;
	default:
		WARN_ON(1);
	}
}

static unsigned omap_dma_read(unsigned type, void __iomem *addr)
{
	unsigned val;

	switch (type) {
	case OMAP_DMA_REG_16BIT:
		val = readw_relaxed(addr);
		break;
	case OMAP_DMA_REG_2X16BIT:
		val = readw_relaxed(addr);
		val |= readw_relaxed(addr + 2) << 16;
		break;
	case OMAP_DMA_REG_32BIT:
		val = readl_relaxed(addr);
		break;
	default:
		WARN_ON(1);
		val = 0;
	}

	return val;
}

static void omap_dma_glbl_write(struct omap_dmadev *od, unsigned reg, unsigned val)
{
	const struct omap_dma_reg *r = od->reg_map + reg;

	WARN_ON(r->stride);

	omap_dma_write(val, r->type, od->base + r->offset);
}

static unsigned omap_dma_glbl_read(struct omap_dmadev *od, unsigned reg)
{
	const struct omap_dma_reg *r = od->reg_map + reg;

	WARN_ON(r->stride);

	return omap_dma_read(r->type, od->base + r->offset);
}

static void omap_dma_chan_write(struct omap_chan *c, unsigned reg, unsigned val)
{
	const struct omap_dma_reg *r = c->reg_map + reg;

	omap_dma_write(val, r->type, c->channel_base + r->offset);
}

static unsigned omap_dma_chan_read(struct omap_chan *c, unsigned reg)
{
	const struct omap_dma_reg *r = c->reg_map + reg;

	return omap_dma_read(r->type, c->channel_base + r->offset);
}

static void omap_dma_clear_csr(struct omap_chan *c)
{
	if (dma_omap1())
		omap_dma_chan_read(c, CSR);
	else
		omap_dma_chan_write(c, CSR, ~0);
}

static unsigned omap_dma_get_csr(struct omap_chan *c)
{
	unsigned val = omap_dma_chan_read(c, CSR);

	if (!dma_omap1())
		omap_dma_chan_write(c, CSR, val);

	return val;
}

static void omap_dma_assign(struct omap_dmadev *od, struct omap_chan *c,
	unsigned lch)
{
	c->channel_base = od->base + od->plat->channel_stride * lch;

	od->lch_map[lch] = c;
}

static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
{
	struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
	uint16_t cicr = d->cicr;

	if (__dma_omap15xx(od->plat->dma_attr))
		omap_dma_chan_write(c, CPC, 0);
	else
		omap_dma_chan_write(c, CDAC, 0);

	omap_dma_clear_csr(c);

	if (d->using_ll) {
		uint32_t cdp = CDP_TMODE_LLIST | CDP_NTYPE_TYPE2 | CDP_FAST;

		if (d->dir == DMA_DEV_TO_MEM)
			cdp |= (CDP_DST_VALID_RELOAD | CDP_SRC_VALID_REUSE);
		else
			cdp |= (CDP_DST_VALID_REUSE | CDP_SRC_VALID_RELOAD);
		omap_dma_chan_write(c, CDP, cdp);

		omap_dma_chan_write(c, CNDP, d->sg[0].t2_desc_paddr);
		omap_dma_chan_write(c, CCDN, 0);
		omap_dma_chan_write(c, CCFN, 0xffff);
		omap_dma_chan_write(c, CCEN, 0xffffff);

		cicr &= ~CICR_BLOCK_IE;
	} else if (od->ll123_supported) {
		omap_dma_chan_write(c, CDP, 0);
	}

	/* Enable interrupts */
	omap_dma_chan_write(c, CICR, cicr);

	/* Enable channel */
	omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE);

	c->running = true;
}

static void omap_dma_drain_chan(struct omap_chan *c)
{
	int i;
	u32 val;

	/* Wait for sDMA FIFO to drain */
	for (i = 0; ; i++) {
		val = omap_dma_chan_read(c, CCR);
		if (!(val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE)))
			break;

		if (i > 100)
			break;

		udelay(5);
	}

	if (val & (CCR_RD_ACTIVE | CCR_WR_ACTIVE))
		dev_err(c->vc.chan.device->dev,
			"DMA drain did not complete on lch %d\n",
			c->dma_ch);
}

static int omap_dma_stop(struct omap_chan *c)
{
	struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
	uint32_t val;

	/* disable irq */
	omap_dma_chan_write(c, CICR, 0);

	omap_dma_clear_csr(c);

	val = omap_dma_chan_read(c, CCR);
	if (od->plat->errata & DMA_ERRATA_i541 && val & CCR_TRIGGER_SRC) {
		uint32_t sysconfig;

		sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
		val = sysconfig & ~DMA_SYSCONFIG_MIDLEMODE_MASK;
		val |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
		omap_dma_glbl_write(od, OCP_SYSCONFIG, val);

		val = omap_dma_chan_read(c, CCR);
		val &= ~CCR_ENABLE;
		omap_dma_chan_write(c, CCR, val);

		if (!(c->ccr & CCR_BUFFERING_DISABLE))
			omap_dma_drain_chan(c);

		omap_dma_glbl_write(od, OCP_SYSCONFIG, sysconfig);
	} else {
		if (!(val & CCR_ENABLE))
			return -EINVAL;

		val &= ~CCR_ENABLE;
		omap_dma_chan_write(c, CCR, val);

		if (!(c->ccr & CCR_BUFFERING_DISABLE))
			omap_dma_drain_chan(c);
	}

	mb();

	if (!__dma_omap15xx(od->plat->dma_attr) && c->cyclic) {
		val = omap_dma_chan_read(c, CLNK_CTRL);

		if (dma_omap1())
			val |= 1 << 14; /* set the STOP_LNK bit */
		else
			val &= ~CLNK_CTRL_ENABLE_LNK;

		omap_dma_chan_write(c, CLNK_CTRL, val);
	}
	c->running = false;
	return 0;
}

static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d)
{
	struct omap_sg *sg = d->sg + c->sgidx;
	unsigned cxsa, cxei, cxfi;

	if (d->dir == DMA_DEV_TO_MEM || d->dir == DMA_MEM_TO_MEM) {
		cxsa = CDSA;
		cxei = CDEI;
		cxfi = CDFI;
	} else {
		cxsa = CSSA;
		cxei = CSEI;
		cxfi = CSFI;
	}

	omap_dma_chan_write(c, cxsa, sg->addr);
	omap_dma_chan_write(c, cxei, sg->ei);
	omap_dma_chan_write(c, cxfi, sg->fi);
	omap_dma_chan_write(c, CEN, sg->en);
	omap_dma_chan_write(c, CFN, sg->fn);

	omap_dma_start(c, d);
	c->sgidx++;
}

static void omap_dma_start_desc(struct omap_chan *c)
{
	struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
	struct omap_desc *d;
	unsigned cxsa, cxei, cxfi;

	if (!vd) {
		c->desc = NULL;
		return;
	}

	list_del(&vd->node);

	c->desc = d = to_omap_dma_desc(&vd->tx);
	c->sgidx = 0;

	/*
	 * This provides the necessary barrier to ensure data held in
	 * DMA coherent memory is visible to the DMA engine prior to
	 * the transfer starting.
	 */
	mb();

	omap_dma_chan_write(c, CCR, d->ccr);
	if (dma_omap1())
		omap_dma_chan_write(c, CCR2, d->ccr >> 16);

	if (d->dir == DMA_DEV_TO_MEM || d->dir == DMA_MEM_TO_MEM) {
		cxsa = CSSA;
		cxei = CSEI;
		cxfi = CSFI;
	} else {
		cxsa = CDSA;
		cxei = CDEI;
		cxfi = CDFI;
	}

	omap_dma_chan_write(c, cxsa, d->dev_addr);
	omap_dma_chan_write(c, cxei, d->ei);
	omap_dma_chan_write(c, cxfi, d->fi);
	omap_dma_chan_write(c, CSDP, d->csdp);
	omap_dma_chan_write(c, CLNK_CTRL, d->clnk_ctrl);

	omap_dma_start_sg(c, d);
}

static void omap_dma_callback(int ch, u16 status, void *data)
{
	struct omap_chan *c = data;
	struct omap_desc *d;
	unsigned long flags;

	spin_lock_irqsave(&c->vc.lock, flags);
	d = c->desc;
	if (d) {
		if (c->cyclic) {
			vchan_cyclic_callback(&d->vd);
		} else if (d->using_ll || c->sgidx == d->sglen) {
			omap_dma_start_desc(c);
			vchan_cookie_complete(&d->vd);
		} else {
			omap_dma_start_sg(c, d);
		}
	}
	spin_unlock_irqrestore(&c->vc.lock, flags);
}

static irqreturn_t omap_dma_irq(int irq, void *devid)
{
	struct omap_dmadev *od = devid;
	unsigned status, channel;

	spin_lock(&od->irq_lock);

	status = omap_dma_glbl_read(od, IRQSTATUS_L1);
	status &= od->irq_enable_mask;
	if (status == 0) {
		spin_unlock(&od->irq_lock);
		return IRQ_NONE;
	}

	while ((channel = ffs(status)) != 0) {
		unsigned mask, csr;
		struct omap_chan *c;

		channel -= 1;
		mask = BIT(channel);
		status &= ~mask;

		c = od->lch_map[channel];
		if (c == NULL) {
			/* This should never happen */
			dev_err(od->ddev.dev, "invalid channel %u\n", channel);
			continue;
		}

		csr = omap_dma_get_csr(c);
		omap_dma_glbl_write(od, IRQSTATUS_L1, mask);

		omap_dma_callback(channel, csr, c);
	}

	spin_unlock(&od->irq_lock);

	return IRQ_HANDLED;
}

static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
{
	struct omap_dmadev *od = to_omap_dma_dev(chan->device);
	struct omap_chan *c = to_omap_dma_chan(chan);
	struct device *dev = od->ddev.dev;
	int ret;

	if (od->legacy) {
		ret = omap_request_dma(c->dma_sig, "DMA engine",
				       omap_dma_callback, c, &c->dma_ch);
	} else {
		ret = omap_request_dma(c->dma_sig, "DMA engine", NULL, NULL,
				       &c->dma_ch);
	}

	dev_dbg(dev, "allocating channel %u for %u\n", c->dma_ch, c->dma_sig);

	if (ret >= 0) {
		omap_dma_assign(od, c, c->dma_ch);

		if (!od->legacy) {
			unsigned val;

			spin_lock_irq(&od->irq_lock);
			val = BIT(c->dma_ch);
			omap_dma_glbl_write(od, IRQSTATUS_L1, val);
			od->irq_enable_mask |= val;
			omap_dma_glbl_write(od, IRQENABLE_L1, od->irq_enable_mask);

			val = omap_dma_glbl_read(od, IRQENABLE_L0);
			val &= ~BIT(c->dma_ch);
			omap_dma_glbl_write(od, IRQENABLE_L0, val);
			spin_unlock_irq(&od->irq_lock);
		}
	}

	if (dma_omap1()) {
		if (__dma_omap16xx(od->plat->dma_attr)) {
			c->ccr = CCR_OMAP31_DISABLE;
			/* Duplicate what plat-omap/dma.c does */
			c->ccr |= c->dma_ch + 1;
		} else {
			c->ccr = c->dma_sig & 0x1f;
		}
	} else {
		c->ccr = c->dma_sig & 0x1f;
		c->ccr |= (c->dma_sig & ~0x1f) << 14;
	}
	if (od->plat->errata & DMA_ERRATA_IFRAME_BUFFERING)
		c->ccr |= CCR_BUFFERING_DISABLE;

	return ret;
}

static void omap_dma_free_chan_resources(struct dma_chan *chan)
{
	struct omap_dmadev *od = to_omap_dma_dev(chan->device);
	struct omap_chan *c = to_omap_dma_chan(chan);

	if (!od->legacy) {
		spin_lock_irq(&od->irq_lock);
		od->irq_enable_mask &= ~BIT(c->dma_ch);
		omap_dma_glbl_write(od, IRQENABLE_L1, od->irq_enable_mask);
		spin_unlock_irq(&od->irq_lock);
	}

	c->channel_base = NULL;
	od->lch_map[c->dma_ch] = NULL;
	vchan_free_chan_resources(&c->vc);
	omap_free_dma(c->dma_ch);

	dev_dbg(od->ddev.dev, "freeing channel %u used for %u\n", c->dma_ch,
		c->dma_sig);
	c->dma_sig = 0;
}

static size_t omap_dma_sg_size(struct omap_sg *sg)
{
	return sg->en * sg->fn;
}

static size_t omap_dma_desc_size(struct omap_desc *d)
{
	unsigned i;
	size_t size;

	for (size = i = 0; i < d->sglen; i++)
		size += omap_dma_sg_size(&d->sg[i]);

	return size * es_bytes[d->es];
}

static size_t omap_dma_desc_size_pos(struct omap_desc *d, dma_addr_t addr)
{
	unsigned i;
	size_t size, es_size = es_bytes[d->es];

	for (size = i = 0; i < d->sglen; i++) {
		size_t this_size = omap_dma_sg_size(&d->sg[i]) * es_size;

		if (size)
			size += this_size;
		else if (addr >= d->sg[i].addr &&
			 addr < d->sg[i].addr + this_size)
			size += d->sg[i].addr + this_size - addr;
	}
	return size;
}

/*
 * OMAP 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
 * read before the DMA controller finished disabling the channel.
 */
static uint32_t omap_dma_chan_read_3_3(struct omap_chan *c, unsigned reg)
{
	struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
	uint32_t val;

	val = omap_dma_chan_read(c, reg);
	if (val == 0 && od->plat->errata & DMA_ERRATA_3_3)
		val = omap_dma_chan_read(c, reg);

	return val;
}

static dma_addr_t omap_dma_get_src_pos(struct omap_chan *c)
{
	struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
	dma_addr_t addr, cdac;

	if (__dma_omap15xx(od->plat->dma_attr)) {
		addr = omap_dma_chan_read(c, CPC);
	} else {
		addr = omap_dma_chan_read_3_3(c, CSAC);
		cdac = omap_dma_chan_read_3_3(c, CDAC);

		/*
		 * CDAC == 0 indicates that the DMA transfer on the channel has
		 * not been started (no data has been transferred so far).
		 * Return the programmed source start address in this case.
		 */
		if (cdac == 0)
			addr = omap_dma_chan_read(c, CSSA);
	}

	if (dma_omap1())
		addr |= omap_dma_chan_read(c, CSSA) & 0xffff0000;

	return addr;
}

static dma_addr_t omap_dma_get_dst_pos(struct omap_chan *c)
{
	struct omap_dmadev *od = to_omap_dma_dev(c->vc.chan.device);
	dma_addr_t addr;

	if (__dma_omap15xx(od->plat->dma_attr)) {
		addr = omap_dma_chan_read(c, CPC);
	} else {
		addr = omap_dma_chan_read_3_3(c, CDAC);

		/*
		 * CDAC == 0 indicates that the DMA transfer on the channel
		 * has not been started (no data has been transferred so
		 * far).  Return the programmed destination start address in
		 * this case.
		 */
		if (addr == 0)
			addr = omap_dma_chan_read(c, CDSA);
	}

	if (dma_omap1())
		addr |= omap_dma_chan_read(c, CDSA) & 0xffff0000;

	return addr;
}

static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
	dma_cookie_t cookie, struct dma_tx_state *txstate)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	struct virt_dma_desc *vd;
	enum dma_status ret;
	unsigned long flags;

	ret = dma_cookie_status(chan, cookie, txstate);

	if (!c->paused && c->running) {
		uint32_t ccr = omap_dma_chan_read(c, CCR);
		/*
		 * The channel is no longer active, set the return value
		 * accordingly
		 */
		if (!(ccr & CCR_ENABLE))
			ret = DMA_COMPLETE;
	}

	if (ret == DMA_COMPLETE || !txstate)
		return ret;

	spin_lock_irqsave(&c->vc.lock, flags);
	vd = vchan_find_desc(&c->vc, cookie);
	if (vd) {
		txstate->residue = omap_dma_desc_size(to_omap_dma_desc(&vd->tx));
	} else if (c->desc && c->desc->vd.tx.cookie == cookie) {
		struct omap_desc *d = c->desc;
		dma_addr_t pos;

		if (d->dir == DMA_MEM_TO_DEV)
			pos = omap_dma_get_src_pos(c);
		else if (d->dir == DMA_DEV_TO_MEM  || d->dir == DMA_MEM_TO_MEM)
			pos = omap_dma_get_dst_pos(c);
		else
			pos = 0;

		txstate->residue = omap_dma_desc_size_pos(d, pos);
	} else {
		txstate->residue = 0;
	}
	if (ret == DMA_IN_PROGRESS && c->paused)
		ret = DMA_PAUSED;
	spin_unlock_irqrestore(&c->vc.lock, flags);

	return ret;
}

static void omap_dma_issue_pending(struct dma_chan *chan)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	unsigned long flags;

	spin_lock_irqsave(&c->vc.lock, flags);
	if (vchan_issue_pending(&c->vc) && !c->desc)
		omap_dma_start_desc(c);
	spin_unlock_irqrestore(&c->vc.lock, flags);
}

static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
	struct dma_chan *chan, struct scatterlist *sgl, unsigned sglen,
	enum dma_transfer_direction dir, unsigned long tx_flags, void *context)
{
	struct omap_dmadev *od = to_omap_dma_dev(chan->device);
	struct omap_chan *c = to_omap_dma_chan(chan);
	enum dma_slave_buswidth dev_width;
	struct scatterlist *sgent;
	struct omap_desc *d;
	dma_addr_t dev_addr;
	unsigned i, es, en, frame_bytes;
	bool ll_failed = false;
	u32 burst;
	u32 port_window, port_window_bytes;

	if (dir == DMA_DEV_TO_MEM) {
		dev_addr = c->cfg.src_addr;
		dev_width = c->cfg.src_addr_width;
		burst = c->cfg.src_maxburst;
		port_window = c->cfg.src_port_window_size;
	} else if (dir == DMA_MEM_TO_DEV) {
		dev_addr = c->cfg.dst_addr;
		dev_width = c->cfg.dst_addr_width;
		burst = c->cfg.dst_maxburst;
		port_window = c->cfg.dst_port_window_size;
	} else {
		dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
		return NULL;
	}

	/* Bus width translates to the element size (ES) */
	switch (dev_width) {
	case DMA_SLAVE_BUSWIDTH_1_BYTE:
		es = CSDP_DATA_TYPE_8;
		break;
	case DMA_SLAVE_BUSWIDTH_2_BYTES:
		es = CSDP_DATA_TYPE_16;
		break;
	case DMA_SLAVE_BUSWIDTH_4_BYTES:
		es = CSDP_DATA_TYPE_32;
		break;
	default: /* not reached */
		return NULL;
	}

	/* Now allocate and setup the descriptor. */
	d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
	if (!d)
		return NULL;

	d->dir = dir;
	d->dev_addr = dev_addr;
	d->es = es;

	/* When the port_window is used, one frame must cover the window */
	if (port_window) {
		burst = port_window;
		port_window_bytes = port_window * es_bytes[es];

		d->ei = 1;
		/*
		 * One frame covers the port_window and by  configure
		 * the source frame index to be -1 * (port_window - 1)
		 * we instruct the sDMA that after a frame is processed
		 * it should move back to the start of the window.
		 */
		d->fi = -(port_window_bytes - 1);
	}

	d->ccr = c->ccr | CCR_SYNC_FRAME;
	if (dir == DMA_DEV_TO_MEM) {
		d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;

		d->ccr |= CCR_DST_AMODE_POSTINC;
		if (port_window) {
			d->ccr |= CCR_SRC_AMODE_DBLIDX;

			if (port_window_bytes >= 64)
				d->csdp |= CSDP_SRC_BURST_64;
			else if (port_window_bytes >= 32)
				d->csdp |= CSDP_SRC_BURST_32;
			else if (port_window_bytes >= 16)
				d->csdp |= CSDP_SRC_BURST_16;

		} else {
			d->ccr |= CCR_SRC_AMODE_CONSTANT;
		}
	} else {
		d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED;

		d->ccr |= CCR_SRC_AMODE_POSTINC;
		if (port_window) {
			d->ccr |= CCR_DST_AMODE_DBLIDX;

			if (port_window_bytes >= 64)
				d->csdp |= CSDP_DST_BURST_64;
			else if (port_window_bytes >= 32)
				d->csdp |= CSDP_DST_BURST_32;
			else if (port_window_bytes >= 16)
				d->csdp |= CSDP_DST_BURST_16;
		} else {
			d->ccr |= CCR_DST_AMODE_CONSTANT;
		}
	}

	d->cicr = CICR_DROP_IE | CICR_BLOCK_IE;
	d->csdp |= es;

	if (dma_omap1()) {
		d->cicr |= CICR_TOUT_IE;

		if (dir == DMA_DEV_TO_MEM)
			d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_TIPB;
		else
			d->csdp |= CSDP_DST_PORT_TIPB | CSDP_SRC_PORT_EMIFF;
	} else {
		if (dir == DMA_DEV_TO_MEM)
			d->ccr |= CCR_TRIGGER_SRC;

		d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;

		if (port_window)
			d->csdp |= CSDP_WRITE_LAST_NON_POSTED;
	}
	if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS)
		d->clnk_ctrl = c->dma_ch;

	/*
	 * Build our scatterlist entries: each contains the address,
	 * the number of elements (EN) in each frame, and the number of
	 * frames (FN).  Number of bytes for this entry = ES * EN * FN.
	 *
	 * Burst size translates to number of elements with frame sync.
	 * Note: DMA engine defines burst to be the number of dev-width
	 * transfers.
	 */
	en = burst;
	frame_bytes = es_bytes[es] * en;

	if (sglen >= 2)
		d->using_ll = od->ll123_supported;

	for_each_sg(sgl, sgent, sglen, i) {
		struct omap_sg *osg = &d->sg[i];

		osg->addr = sg_dma_address(sgent);
		osg->en = en;
		osg->fn = sg_dma_len(sgent) / frame_bytes;

		if (d->using_ll) {
			osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,
						      &osg->t2_desc_paddr);
			if (!osg->t2_desc) {
				dev_err(chan->device->dev,
					"t2_desc[%d] allocation failed\n", i);
				ll_failed = true;
				d->using_ll = false;
				continue;
			}

			omap_dma_fill_type2_desc(d, i, dir, (i == sglen - 1));
		}
	}

	d->sglen = sglen;

	/* Release the dma_pool entries if one allocation failed */
	if (ll_failed) {
		for (i = 0; i < d->sglen; i++) {
			struct omap_sg *osg = &d->sg[i];

			if (osg->t2_desc) {
				dma_pool_free(od->desc_pool, osg->t2_desc,
					      osg->t2_desc_paddr);
				osg->t2_desc = NULL;
			}
		}
	}

	return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
}

static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
	struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
	size_t period_len, enum dma_transfer_direction dir, unsigned long flags)
{
	struct omap_dmadev *od = to_omap_dma_dev(chan->device);
	struct omap_chan *c = to_omap_dma_chan(chan);
	enum dma_slave_buswidth dev_width;
	struct omap_desc *d;
	dma_addr_t dev_addr;
	unsigned es;
	u32 burst;

	if (dir == DMA_DEV_TO_MEM) {
		dev_addr = c->cfg.src_addr;
		dev_width = c->cfg.src_addr_width;
		burst = c->cfg.src_maxburst;
	} else if (dir == DMA_MEM_TO_DEV) {
		dev_addr = c->cfg.dst_addr;
		dev_width = c->cfg.dst_addr_width;
		burst = c->cfg.dst_maxburst;
	} else {
		dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
		return NULL;
	}

	/* Bus width translates to the element size (ES) */
	switch (dev_width) {
	case DMA_SLAVE_BUSWIDTH_1_BYTE:
		es = CSDP_DATA_TYPE_8;
		break;
	case DMA_SLAVE_BUSWIDTH_2_BYTES:
		es = CSDP_DATA_TYPE_16;
		break;
	case DMA_SLAVE_BUSWIDTH_4_BYTES:
		es = CSDP_DATA_TYPE_32;
		break;
	default: /* not reached */
		return NULL;
	}

	/* Now allocate and setup the descriptor. */
	d = kzalloc(sizeof(*d) + sizeof(d->sg[0]), GFP_ATOMIC);
	if (!d)
		return NULL;

	d->dir = dir;
	d->dev_addr = dev_addr;
	d->fi = burst;
	d->es = es;
	d->sg[0].addr = buf_addr;
	d->sg[0].en = period_len / es_bytes[es];
	d->sg[0].fn = buf_len / period_len;
	d->sglen = 1;

	d->ccr = c->ccr;
	if (dir == DMA_DEV_TO_MEM)
		d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT;
	else
		d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC;

	d->cicr = CICR_DROP_IE;
	if (flags & DMA_PREP_INTERRUPT)
		d->cicr |= CICR_FRAME_IE;

	d->csdp = es;

	if (dma_omap1()) {
		d->cicr |= CICR_TOUT_IE;

		if (dir == DMA_DEV_TO_MEM)
			d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_MPUI;
		else
			d->csdp |= CSDP_DST_PORT_MPUI | CSDP_SRC_PORT_EMIFF;
	} else {
		if (burst)
			d->ccr |= CCR_SYNC_PACKET;
		else
			d->ccr |= CCR_SYNC_ELEMENT;

		if (dir == DMA_DEV_TO_MEM) {
			d->ccr |= CCR_TRIGGER_SRC;
			d->csdp |= CSDP_DST_PACKED;
		} else {
			d->csdp |= CSDP_SRC_PACKED;
		}

		d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;

		d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
	}

	if (__dma_omap15xx(od->plat->dma_attr))
		d->ccr |= CCR_AUTO_INIT | CCR_REPEAT;
	else
		d->clnk_ctrl = c->dma_ch | CLNK_CTRL_ENABLE_LNK;

	c->cyclic = true;

	return vchan_tx_prep(&c->vc, &d->vd, flags);
}

static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy(
	struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
	size_t len, unsigned long tx_flags)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	struct omap_desc *d;
	uint8_t data_type;

	d = kzalloc(sizeof(*d) + sizeof(d->sg[0]), GFP_ATOMIC);
	if (!d)
		return NULL;

	data_type = __ffs((src | dest | len));
	if (data_type > CSDP_DATA_TYPE_32)
		data_type = CSDP_DATA_TYPE_32;

	d->dir = DMA_MEM_TO_MEM;
	d->dev_addr = src;
	d->fi = 0;
	d->es = data_type;
	d->sg[0].en = len / BIT(data_type);
	d->sg[0].fn = 1;
	d->sg[0].addr = dest;
	d->sglen = 1;
	d->ccr = c->ccr;
	d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC;

	d->cicr = CICR_DROP_IE | CICR_FRAME_IE;

	d->csdp = data_type;

	if (dma_omap1()) {
		d->cicr |= CICR_TOUT_IE;
		d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_EMIFF;
	} else {
		d->csdp |= CSDP_DST_PACKED | CSDP_SRC_PACKED;
		d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
		d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
	}

	return vchan_tx_prep(&c->vc, &d->vd, tx_flags);
}

static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved(
	struct dma_chan *chan, struct dma_interleaved_template *xt,
	unsigned long flags)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	struct omap_desc *d;
	struct omap_sg *sg;
	uint8_t data_type;
	size_t src_icg, dst_icg;

	/* Slave mode is not supported */
	if (is_slave_direction(xt->dir))
		return NULL;

	if (xt->frame_size != 1 || xt->numf == 0)
		return NULL;

	d = kzalloc(sizeof(*d) + sizeof(d->sg[0]), GFP_ATOMIC);
	if (!d)
		return NULL;

	data_type = __ffs((xt->src_start | xt->dst_start | xt->sgl[0].size));
	if (data_type > CSDP_DATA_TYPE_32)
		data_type = CSDP_DATA_TYPE_32;

	sg = &d->sg[0];
	d->dir = DMA_MEM_TO_MEM;
	d->dev_addr = xt->src_start;
	d->es = data_type;
	sg->en = xt->sgl[0].size / BIT(data_type);
	sg->fn = xt->numf;
	sg->addr = xt->dst_start;
	d->sglen = 1;
	d->ccr = c->ccr;

	src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]);
	dst_icg = dmaengine_get_dst_icg(xt, &xt->sgl[0]);
	if (src_icg) {
		d->ccr |= CCR_SRC_AMODE_DBLIDX;
		d->ei = 1;
		d->fi = src_icg;
	} else if (xt->src_inc) {
		d->ccr |= CCR_SRC_AMODE_POSTINC;
		d->fi = 0;
	} else {
		dev_err(chan->device->dev,
			"%s: SRC constant addressing is not supported\n",
			__func__);
		kfree(d);
		return NULL;
	}

	if (dst_icg) {
		d->ccr |= CCR_DST_AMODE_DBLIDX;
		sg->ei = 1;
		sg->fi = dst_icg;
	} else if (xt->dst_inc) {
		d->ccr |= CCR_DST_AMODE_POSTINC;
		sg->fi = 0;
	} else {
		dev_err(chan->device->dev,
			"%s: DST constant addressing is not supported\n",
			__func__);
		kfree(d);
		return NULL;
	}

	d->cicr = CICR_DROP_IE | CICR_FRAME_IE;

	d->csdp = data_type;

	if (dma_omap1()) {
		d->cicr |= CICR_TOUT_IE;
		d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_EMIFF;
	} else {
		d->csdp |= CSDP_DST_PACKED | CSDP_SRC_PACKED;
		d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE;
		d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64;
	}

	return vchan_tx_prep(&c->vc, &d->vd, flags);
}

static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
{
	struct omap_chan *c = to_omap_dma_chan(chan);

	if (cfg->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
	    cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
		return -EINVAL;

	memcpy(&c->cfg, cfg, sizeof(c->cfg));

	return 0;
}

static int omap_dma_terminate_all(struct dma_chan *chan)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	unsigned long flags;
	LIST_HEAD(head);

	spin_lock_irqsave(&c->vc.lock, flags);

	/*
	 * Stop DMA activity: we assume the callback will not be called
	 * after omap_dma_stop() returns (even if it does, it will see
	 * c->desc is NULL and exit.)
	 */
	if (c->desc) {
		omap_dma_desc_free(&c->desc->vd);
		c->desc = NULL;
		/* Avoid stopping the dma twice */
		if (!c->paused)
			omap_dma_stop(c);
	}

	c->cyclic = false;
	c->paused = false;

	vchan_get_all_descriptors(&c->vc, &head);
	spin_unlock_irqrestore(&c->vc.lock, flags);
	vchan_dma_desc_free_list(&c->vc, &head);

	return 0;
}

static void omap_dma_synchronize(struct dma_chan *chan)
{
	struct omap_chan *c = to_omap_dma_chan(chan);

	vchan_synchronize(&c->vc);
}

static int omap_dma_pause(struct dma_chan *chan)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	struct omap_dmadev *od = to_omap_dma_dev(chan->device);
	unsigned long flags;
	int ret = -EINVAL;
	bool can_pause = false;

	spin_lock_irqsave(&od->irq_lock, flags);

	if (!c->desc)
		goto out;

	if (c->cyclic)
		can_pause = true;

	/*
	 * We do not allow DMA_MEM_TO_DEV transfers to be paused.
	 * From the AM572x TRM, 16.1.4.18 Disabling a Channel During Transfer:
	 * "When a channel is disabled during a transfer, the channel undergoes
	 * an abort, unless it is hardware-source-synchronized …".
	 * A source-synchronised channel is one where the fetching of data is
	 * under control of the device. In other words, a device-to-memory
	 * transfer. So, a destination-synchronised channel (which would be a
	 * memory-to-device transfer) undergoes an abort if the the CCR_ENABLE
	 * bit is cleared.
	 * From 16.1.4.20.4.6.2 Abort: "If an abort trigger occurs, the channel
	 * aborts immediately after completion of current read/write
	 * transactions and then the FIFO is cleaned up." The term "cleaned up"
	 * is not defined. TI recommends to check that RD_ACTIVE and WR_ACTIVE
	 * are both clear _before_ disabling the channel, otherwise data loss
	 * will occur.
	 * The problem is that if the channel is active, then device activity
	 * can result in DMA activity starting between reading those as both
	 * clear and the write to DMA_CCR to clear the enable bit hitting the
	 * hardware. If the DMA hardware can't drain the data in its FIFO to the
	 * destination, then data loss "might" occur (say if we write to an UART
	 * and the UART is not accepting any further data).
	 */
	else if (c->desc->dir == DMA_DEV_TO_MEM)
		can_pause = true;

	if (can_pause && !c->paused) {
		ret = omap_dma_stop(c);
		if (!ret)
			c->paused = true;
	}
out:
	spin_unlock_irqrestore(&od->irq_lock, flags);

	return ret;
}

static int omap_dma_resume(struct dma_chan *chan)
{
	struct omap_chan *c = to_omap_dma_chan(chan);
	struct omap_dmadev *od = to_omap_dma_dev(chan->device);
	unsigned long flags;
	int ret = -EINVAL;

	spin_lock_irqsave(&od->irq_lock, flags);

	if (c->paused && c->desc) {
		mb();

		/* Restore channel link register */
		omap_dma_chan_write(c, CLNK_CTRL, c->desc->clnk_ctrl);

		omap_dma_start(c, c->desc);
		c->paused = false;
		ret = 0;
	}
	spin_unlock_irqrestore(&od->irq_lock, flags);

	return ret;
}

static int omap_dma_chan_init(struct omap_dmadev *od)
{
	struct omap_chan *c;

	c = kzalloc(sizeof(*c), GFP_KERNEL);
	if (!c)
		return -ENOMEM;

	c->reg_map = od->reg_map;
	c->vc.desc_free = omap_dma_desc_free;
	vchan_init(&c->vc, &od->ddev);

	return 0;
}

static void omap_dma_free(struct omap_dmadev *od)
{
	while (!list_empty(&od->ddev.channels)) {
		struct omap_chan *c = list_first_entry(&od->ddev.channels,
			struct omap_chan, vc.chan.device_node);

		list_del(&c->vc.chan.device_node);
		tasklet_kill(&c->vc.task);
		kfree(c);
	}
}

#define OMAP_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))

static int omap_dma_probe(struct platform_device *pdev)
{
	struct omap_dmadev *od;
	struct resource *res;
	int rc, i, irq;
	u32 lch_count;

	od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
	if (!od)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	od->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(od->base))
		return PTR_ERR(od->base);

	od->plat = omap_get_plat_info();
	if (!od->plat)
		return -EPROBE_DEFER;

	od->reg_map = od->plat->reg_map;

	dma_cap_set(DMA_SLAVE, od->ddev.cap_mask);
	dma_cap_set(DMA_CYCLIC, od->ddev.cap_mask);
	dma_cap_set(DMA_MEMCPY, od->ddev.cap_mask);
	dma_cap_set(DMA_INTERLEAVE, od->ddev.cap_mask);
	od->ddev.device_alloc_chan_resources = omap_dma_alloc_chan_resources;
	od->ddev.device_free_chan_resources = omap_dma_free_chan_resources;
	od->ddev.device_tx_status = omap_dma_tx_status;
	od->ddev.device_issue_pending = omap_dma_issue_pending;
	od->ddev.device_prep_slave_sg = omap_dma_prep_slave_sg;
	od->ddev.device_prep_dma_cyclic = omap_dma_prep_dma_cyclic;
	od->ddev.device_prep_dma_memcpy = omap_dma_prep_dma_memcpy;
	od->ddev.device_prep_interleaved_dma = omap_dma_prep_dma_interleaved;
	od->ddev.device_config = omap_dma_slave_config;
	od->ddev.device_pause = omap_dma_pause;
	od->ddev.device_resume = omap_dma_resume;
	od->ddev.device_terminate_all = omap_dma_terminate_all;
	od->ddev.device_synchronize = omap_dma_synchronize;
	od->ddev.src_addr_widths = OMAP_DMA_BUSWIDTHS;
	od->ddev.dst_addr_widths = OMAP_DMA_BUSWIDTHS;
	od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
	od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
	od->ddev.dev = &pdev->dev;
	INIT_LIST_HEAD(&od->ddev.channels);
	spin_lock_init(&od->lock);
	spin_lock_init(&od->irq_lock);

	/* Number of DMA requests */
	od->dma_requests = OMAP_SDMA_REQUESTS;
	if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
						      "dma-requests",
						      &od->dma_requests)) {
		dev_info(&pdev->dev,
			 "Missing dma-requests property, using %u.\n",
			 OMAP_SDMA_REQUESTS);
	}

	/* Number of available logical channels */
	if (!pdev->dev.of_node) {
		lch_count = od->plat->dma_attr->lch_count;
		if (unlikely(!lch_count))
			lch_count = OMAP_SDMA_CHANNELS;
	} else if (of_property_read_u32(pdev->dev.of_node, "dma-channels",
					&lch_count)) {
		dev_info(&pdev->dev,
			 "Missing dma-channels property, using %u.\n",
			 OMAP_SDMA_CHANNELS);
		lch_count = OMAP_SDMA_CHANNELS;
	}

	od->lch_map = devm_kcalloc(&pdev->dev, lch_count, sizeof(*od->lch_map),
				   GFP_KERNEL);
	if (!od->lch_map)
		return -ENOMEM;

	for (i = 0; i < od->dma_requests; i++) {
		rc = omap_dma_chan_init(od);
		if (rc) {
			omap_dma_free(od);
			return rc;
		}
	}

	irq = platform_get_irq(pdev, 1);
	if (irq <= 0) {
		dev_info(&pdev->dev, "failed to get L1 IRQ: %d\n", irq);
		od->legacy = true;
	} else {
		/* Disable all interrupts */
		od->irq_enable_mask = 0;
		omap_dma_glbl_write(od, IRQENABLE_L1, 0);

		rc = devm_request_irq(&pdev->dev, irq, omap_dma_irq,
				      IRQF_SHARED, "omap-dma-engine", od);
		if (rc)
			return rc;
	}

	if (omap_dma_glbl_read(od, CAPS_0) & CAPS_0_SUPPORT_LL123)
		od->ll123_supported = true;

	od->ddev.filter.map = od->plat->slave_map;
	od->ddev.filter.mapcnt = od->plat->slavecnt;
	od->ddev.filter.fn = omap_dma_filter_fn;

	if (od->ll123_supported) {
		od->desc_pool = dma_pool_create(dev_name(&pdev->dev),
						&pdev->dev,
						sizeof(struct omap_type2_desc),
						4, 0);
		if (!od->desc_pool) {
			dev_err(&pdev->dev,
				"unable to allocate descriptor pool\n");
			od->ll123_supported = false;
		}
	}

	rc = dma_async_device_register(&od->ddev);
	if (rc) {
		pr_warn("OMAP-DMA: failed to register slave DMA engine device: %d\n",
			rc);
		omap_dma_free(od);
		return rc;
	}

	platform_set_drvdata(pdev, od);

	if (pdev->dev.of_node) {
		omap_dma_info.dma_cap = od->ddev.cap_mask;

		/* Device-tree DMA controller registration */
		rc = of_dma_controller_register(pdev->dev.of_node,
				of_dma_simple_xlate, &omap_dma_info);
		if (rc) {
			pr_warn("OMAP-DMA: failed to register DMA controller\n");
			dma_async_device_unregister(&od->ddev);
			omap_dma_free(od);
		}
	}

	dev_info(&pdev->dev, "OMAP DMA engine driver%s\n",
		 od->ll123_supported ? " (LinkedList1/2/3 supported)" : "");

	return rc;
}

static int omap_dma_remove(struct platform_device *pdev)
{
	struct omap_dmadev *od = platform_get_drvdata(pdev);
	int irq;

	if (pdev->dev.of_node)
		of_dma_controller_free(pdev->dev.of_node);

	irq = platform_get_irq(pdev, 1);
	devm_free_irq(&pdev->dev, irq, od);

	dma_async_device_unregister(&od->ddev);

	if (!od->legacy) {
		/* Disable all interrupts */
		omap_dma_glbl_write(od, IRQENABLE_L0, 0);
	}

	if (od->ll123_supported)
		dma_pool_destroy(od->desc_pool);

	omap_dma_free(od);

	return 0;
}

static const struct of_device_id omap_dma_match[] = {
	{ .compatible = "ti,omap2420-sdma", },
	{ .compatible = "ti,omap2430-sdma", },
	{ .compatible = "ti,omap3430-sdma", },
	{ .compatible = "ti,omap3630-sdma", },
	{ .compatible = "ti,omap4430-sdma", },
	{},
};
MODULE_DEVICE_TABLE(of, omap_dma_match);

static struct platform_driver omap_dma_driver = {
	.probe	= omap_dma_probe,
	.remove	= omap_dma_remove,
	.driver = {
		.name = "omap-dma-engine",
		.of_match_table = of_match_ptr(omap_dma_match),
	},
};

bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
{
	if (chan->device->dev->driver == &omap_dma_driver.driver) {
		struct omap_dmadev *od = to_omap_dma_dev(chan->device);
		struct omap_chan *c = to_omap_dma_chan(chan);
		unsigned req = *(unsigned *)param;

		if (req <= od->dma_requests) {
			c->dma_sig = req;
			return true;
		}
	}
	return false;
}
EXPORT_SYMBOL_GPL(omap_dma_filter_fn);

static int omap_dma_init(void)
{
	return platform_driver_register(&omap_dma_driver);
}
subsys_initcall(omap_dma_init);

static void __exit omap_dma_exit(void)
{
	platform_driver_unregister(&omap_dma_driver);
}
module_exit(omap_dma_exit);

MODULE_AUTHOR("Russell King");
MODULE_LICENSE("GPL");
