cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

moxart-dma.c (16394B)


      1/*
      2 * MOXA ART SoCs DMA Engine support.
      3 *
      4 * Copyright (C) 2013 Jonas Jensen
      5 *
      6 * Jonas Jensen <jonas.jensen@gmail.com>
      7 *
      8 * This file is licensed under the terms of the GNU General Public
      9 * License version 2.  This program is licensed "as is" without any
     10 * warranty of any kind, whether express or implied.
     11 */
     12
     13#include <linux/dmaengine.h>
     14#include <linux/dma-mapping.h>
     15#include <linux/err.h>
     16#include <linux/init.h>
     17#include <linux/interrupt.h>
     18#include <linux/list.h>
     19#include <linux/module.h>
     20#include <linux/platform_device.h>
     21#include <linux/slab.h>
     22#include <linux/spinlock.h>
     23#include <linux/of_address.h>
     24#include <linux/of_irq.h>
     25#include <linux/of_dma.h>
     26#include <linux/bitops.h>
     27
     28#include <asm/cacheflush.h>
     29
     30#include "dmaengine.h"
     31#include "virt-dma.h"
     32
     33#define APB_DMA_MAX_CHANNEL			4
     34
     35#define REG_OFF_ADDRESS_SOURCE			0
     36#define REG_OFF_ADDRESS_DEST			4
     37#define REG_OFF_CYCLES				8
     38#define REG_OFF_CTRL				12
     39#define REG_OFF_CHAN_SIZE			16
     40
     41#define APB_DMA_ENABLE				BIT(0)
     42#define APB_DMA_FIN_INT_STS			BIT(1)
     43#define APB_DMA_FIN_INT_EN			BIT(2)
     44#define APB_DMA_BURST_MODE			BIT(3)
     45#define APB_DMA_ERR_INT_STS			BIT(4)
     46#define APB_DMA_ERR_INT_EN			BIT(5)
     47
     48/*
     49 * Unset: APB
     50 * Set:   AHB
     51 */
     52#define APB_DMA_SOURCE_SELECT			0x40
     53#define APB_DMA_DEST_SELECT			0x80
     54
     55#define APB_DMA_SOURCE				0x100
     56#define APB_DMA_DEST				0x1000
     57
     58#define APB_DMA_SOURCE_MASK			0x700
     59#define APB_DMA_DEST_MASK			0x7000
     60
     61/*
     62 * 000: No increment
     63 * 001: +1 (Burst=0), +4  (Burst=1)
     64 * 010: +2 (Burst=0), +8  (Burst=1)
     65 * 011: +4 (Burst=0), +16 (Burst=1)
     66 * 101: -1 (Burst=0), -4  (Burst=1)
     67 * 110: -2 (Burst=0), -8  (Burst=1)
     68 * 111: -4 (Burst=0), -16 (Burst=1)
     69 */
     70#define APB_DMA_SOURCE_INC_0			0
     71#define APB_DMA_SOURCE_INC_1_4			0x100
     72#define APB_DMA_SOURCE_INC_2_8			0x200
     73#define APB_DMA_SOURCE_INC_4_16			0x300
     74#define APB_DMA_SOURCE_DEC_1_4			0x500
     75#define APB_DMA_SOURCE_DEC_2_8			0x600
     76#define APB_DMA_SOURCE_DEC_4_16			0x700
     77#define APB_DMA_DEST_INC_0			0
     78#define APB_DMA_DEST_INC_1_4			0x1000
     79#define APB_DMA_DEST_INC_2_8			0x2000
     80#define APB_DMA_DEST_INC_4_16			0x3000
     81#define APB_DMA_DEST_DEC_1_4			0x5000
     82#define APB_DMA_DEST_DEC_2_8			0x6000
     83#define APB_DMA_DEST_DEC_4_16			0x7000
     84
     85/*
     86 * Request signal select source/destination address for DMA hardware handshake.
     87 *
     88 * The request line number is a property of the DMA controller itself,
     89 * e.g. MMC must always request channels where dma_slave_config->slave_id is 5.
     90 *
     91 * 0:    No request / Grant signal
     92 * 1-15: Request    / Grant signal
     93 */
     94#define APB_DMA_SOURCE_REQ_NO			0x1000000
     95#define APB_DMA_SOURCE_REQ_NO_MASK		0xf000000
     96#define APB_DMA_DEST_REQ_NO			0x10000
     97#define APB_DMA_DEST_REQ_NO_MASK		0xf0000
     98
     99#define APB_DMA_DATA_WIDTH			0x100000
    100#define APB_DMA_DATA_WIDTH_MASK			0x300000
    101/*
    102 * Data width of transfer:
    103 *
    104 * 00: Word
    105 * 01: Half
    106 * 10: Byte
    107 */
    108#define APB_DMA_DATA_WIDTH_4			0
    109#define APB_DMA_DATA_WIDTH_2			0x100000
    110#define APB_DMA_DATA_WIDTH_1			0x200000
    111
    112#define APB_DMA_CYCLES_MASK			0x00ffffff
    113
    114#define MOXART_DMA_DATA_TYPE_S8			0x00
    115#define MOXART_DMA_DATA_TYPE_S16		0x01
    116#define MOXART_DMA_DATA_TYPE_S32		0x02
    117
    118struct moxart_sg {
    119	dma_addr_t addr;
    120	uint32_t len;
    121};
    122
    123struct moxart_desc {
    124	enum dma_transfer_direction	dma_dir;
    125	dma_addr_t			dev_addr;
    126	unsigned int			sglen;
    127	unsigned int			dma_cycles;
    128	struct virt_dma_desc		vd;
    129	uint8_t				es;
    130	struct moxart_sg		sg[];
    131};
    132
    133struct moxart_chan {
    134	struct virt_dma_chan		vc;
    135
    136	void __iomem			*base;
    137	struct moxart_desc		*desc;
    138
    139	struct dma_slave_config		cfg;
    140
    141	bool				allocated;
    142	bool				error;
    143	int				ch_num;
    144	unsigned int			line_reqno;
    145	unsigned int			sgidx;
    146};
    147
    148struct moxart_dmadev {
    149	struct dma_device		dma_slave;
    150	struct moxart_chan		slave_chans[APB_DMA_MAX_CHANNEL];
    151	unsigned int			irq;
    152};
    153
    154struct moxart_filter_data {
    155	struct moxart_dmadev		*mdc;
    156	struct of_phandle_args		*dma_spec;
    157};
    158
    159static const unsigned int es_bytes[] = {
    160	[MOXART_DMA_DATA_TYPE_S8] = 1,
    161	[MOXART_DMA_DATA_TYPE_S16] = 2,
    162	[MOXART_DMA_DATA_TYPE_S32] = 4,
    163};
    164
    165static struct device *chan2dev(struct dma_chan *chan)
    166{
    167	return &chan->dev->device;
    168}
    169
    170static inline struct moxart_chan *to_moxart_dma_chan(struct dma_chan *c)
    171{
    172	return container_of(c, struct moxart_chan, vc.chan);
    173}
    174
    175static inline struct moxart_desc *to_moxart_dma_desc(
    176	struct dma_async_tx_descriptor *t)
    177{
    178	return container_of(t, struct moxart_desc, vd.tx);
    179}
    180
    181static void moxart_dma_desc_free(struct virt_dma_desc *vd)
    182{
    183	kfree(container_of(vd, struct moxart_desc, vd));
    184}
    185
    186static int moxart_terminate_all(struct dma_chan *chan)
    187{
    188	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    189	unsigned long flags;
    190	LIST_HEAD(head);
    191	u32 ctrl;
    192
    193	dev_dbg(chan2dev(chan), "%s: ch=%p\n", __func__, ch);
    194
    195	spin_lock_irqsave(&ch->vc.lock, flags);
    196
    197	if (ch->desc) {
    198		moxart_dma_desc_free(&ch->desc->vd);
    199		ch->desc = NULL;
    200	}
    201
    202	ctrl = readl(ch->base + REG_OFF_CTRL);
    203	ctrl &= ~(APB_DMA_ENABLE | APB_DMA_FIN_INT_EN | APB_DMA_ERR_INT_EN);
    204	writel(ctrl, ch->base + REG_OFF_CTRL);
    205
    206	vchan_get_all_descriptors(&ch->vc, &head);
    207	spin_unlock_irqrestore(&ch->vc.lock, flags);
    208	vchan_dma_desc_free_list(&ch->vc, &head);
    209
    210	return 0;
    211}
    212
    213static int moxart_slave_config(struct dma_chan *chan,
    214			       struct dma_slave_config *cfg)
    215{
    216	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    217	u32 ctrl;
    218
    219	ch->cfg = *cfg;
    220
    221	ctrl = readl(ch->base + REG_OFF_CTRL);
    222	ctrl |= APB_DMA_BURST_MODE;
    223	ctrl &= ~(APB_DMA_DEST_MASK | APB_DMA_SOURCE_MASK);
    224	ctrl &= ~(APB_DMA_DEST_REQ_NO_MASK | APB_DMA_SOURCE_REQ_NO_MASK);
    225
    226	switch (ch->cfg.src_addr_width) {
    227	case DMA_SLAVE_BUSWIDTH_1_BYTE:
    228		ctrl |= APB_DMA_DATA_WIDTH_1;
    229		if (ch->cfg.direction != DMA_MEM_TO_DEV)
    230			ctrl |= APB_DMA_DEST_INC_1_4;
    231		else
    232			ctrl |= APB_DMA_SOURCE_INC_1_4;
    233		break;
    234	case DMA_SLAVE_BUSWIDTH_2_BYTES:
    235		ctrl |= APB_DMA_DATA_WIDTH_2;
    236		if (ch->cfg.direction != DMA_MEM_TO_DEV)
    237			ctrl |= APB_DMA_DEST_INC_2_8;
    238		else
    239			ctrl |= APB_DMA_SOURCE_INC_2_8;
    240		break;
    241	case DMA_SLAVE_BUSWIDTH_4_BYTES:
    242		ctrl &= ~APB_DMA_DATA_WIDTH;
    243		if (ch->cfg.direction != DMA_MEM_TO_DEV)
    244			ctrl |= APB_DMA_DEST_INC_4_16;
    245		else
    246			ctrl |= APB_DMA_SOURCE_INC_4_16;
    247		break;
    248	default:
    249		return -EINVAL;
    250	}
    251
    252	if (ch->cfg.direction == DMA_MEM_TO_DEV) {
    253		ctrl &= ~APB_DMA_DEST_SELECT;
    254		ctrl |= APB_DMA_SOURCE_SELECT;
    255		ctrl |= (ch->line_reqno << 16 &
    256			 APB_DMA_DEST_REQ_NO_MASK);
    257	} else {
    258		ctrl |= APB_DMA_DEST_SELECT;
    259		ctrl &= ~APB_DMA_SOURCE_SELECT;
    260		ctrl |= (ch->line_reqno << 24 &
    261			 APB_DMA_SOURCE_REQ_NO_MASK);
    262	}
    263
    264	writel(ctrl, ch->base + REG_OFF_CTRL);
    265
    266	return 0;
    267}
    268
    269static struct dma_async_tx_descriptor *moxart_prep_slave_sg(
    270	struct dma_chan *chan, struct scatterlist *sgl,
    271	unsigned int sg_len, enum dma_transfer_direction dir,
    272	unsigned long tx_flags, void *context)
    273{
    274	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    275	struct moxart_desc *d;
    276	enum dma_slave_buswidth dev_width;
    277	dma_addr_t dev_addr;
    278	struct scatterlist *sgent;
    279	unsigned int es;
    280	unsigned int i;
    281
    282	if (!is_slave_direction(dir)) {
    283		dev_err(chan2dev(chan), "%s: invalid DMA direction\n",
    284			__func__);
    285		return NULL;
    286	}
    287
    288	if (dir == DMA_DEV_TO_MEM) {
    289		dev_addr = ch->cfg.src_addr;
    290		dev_width = ch->cfg.src_addr_width;
    291	} else {
    292		dev_addr = ch->cfg.dst_addr;
    293		dev_width = ch->cfg.dst_addr_width;
    294	}
    295
    296	switch (dev_width) {
    297	case DMA_SLAVE_BUSWIDTH_1_BYTE:
    298		es = MOXART_DMA_DATA_TYPE_S8;
    299		break;
    300	case DMA_SLAVE_BUSWIDTH_2_BYTES:
    301		es = MOXART_DMA_DATA_TYPE_S16;
    302		break;
    303	case DMA_SLAVE_BUSWIDTH_4_BYTES:
    304		es = MOXART_DMA_DATA_TYPE_S32;
    305		break;
    306	default:
    307		dev_err(chan2dev(chan), "%s: unsupported data width (%u)\n",
    308			__func__, dev_width);
    309		return NULL;
    310	}
    311
    312	d = kzalloc(struct_size(d, sg, sg_len), GFP_ATOMIC);
    313	if (!d)
    314		return NULL;
    315
    316	d->dma_dir = dir;
    317	d->dev_addr = dev_addr;
    318	d->es = es;
    319
    320	for_each_sg(sgl, sgent, sg_len, i) {
    321		d->sg[i].addr = sg_dma_address(sgent);
    322		d->sg[i].len = sg_dma_len(sgent);
    323	}
    324
    325	d->sglen = sg_len;
    326
    327	ch->error = 0;
    328
    329	return vchan_tx_prep(&ch->vc, &d->vd, tx_flags);
    330}
    331
    332static struct dma_chan *moxart_of_xlate(struct of_phandle_args *dma_spec,
    333					struct of_dma *ofdma)
    334{
    335	struct moxart_dmadev *mdc = ofdma->of_dma_data;
    336	struct dma_chan *chan;
    337	struct moxart_chan *ch;
    338
    339	chan = dma_get_any_slave_channel(&mdc->dma_slave);
    340	if (!chan)
    341		return NULL;
    342
    343	ch = to_moxart_dma_chan(chan);
    344	ch->line_reqno = dma_spec->args[0];
    345
    346	return chan;
    347}
    348
    349static int moxart_alloc_chan_resources(struct dma_chan *chan)
    350{
    351	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    352
    353	dev_dbg(chan2dev(chan), "%s: allocating channel #%u\n",
    354		__func__, ch->ch_num);
    355	ch->allocated = 1;
    356
    357	return 0;
    358}
    359
    360static void moxart_free_chan_resources(struct dma_chan *chan)
    361{
    362	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    363
    364	vchan_free_chan_resources(&ch->vc);
    365
    366	dev_dbg(chan2dev(chan), "%s: freeing channel #%u\n",
    367		__func__, ch->ch_num);
    368	ch->allocated = 0;
    369}
    370
    371static void moxart_dma_set_params(struct moxart_chan *ch, dma_addr_t src_addr,
    372				  dma_addr_t dst_addr)
    373{
    374	writel(src_addr, ch->base + REG_OFF_ADDRESS_SOURCE);
    375	writel(dst_addr, ch->base + REG_OFF_ADDRESS_DEST);
    376}
    377
    378static void moxart_set_transfer_params(struct moxart_chan *ch, unsigned int len)
    379{
    380	struct moxart_desc *d = ch->desc;
    381	unsigned int sglen_div = es_bytes[d->es];
    382
    383	d->dma_cycles = len >> sglen_div;
    384
    385	/*
    386	 * There are 4 cycles on 64 bytes copied, i.e. one cycle copies 16
    387	 * bytes ( when width is APB_DMAB_DATA_WIDTH_4 ).
    388	 */
    389	writel(d->dma_cycles, ch->base + REG_OFF_CYCLES);
    390
    391	dev_dbg(chan2dev(&ch->vc.chan), "%s: set %u DMA cycles (len=%u)\n",
    392		__func__, d->dma_cycles, len);
    393}
    394
    395static void moxart_start_dma(struct moxart_chan *ch)
    396{
    397	u32 ctrl;
    398
    399	ctrl = readl(ch->base + REG_OFF_CTRL);
    400	ctrl |= (APB_DMA_ENABLE | APB_DMA_FIN_INT_EN | APB_DMA_ERR_INT_EN);
    401	writel(ctrl, ch->base + REG_OFF_CTRL);
    402}
    403
    404static void moxart_dma_start_sg(struct moxart_chan *ch, unsigned int idx)
    405{
    406	struct moxart_desc *d = ch->desc;
    407	struct moxart_sg *sg = ch->desc->sg + idx;
    408
    409	if (ch->desc->dma_dir == DMA_MEM_TO_DEV)
    410		moxart_dma_set_params(ch, sg->addr, d->dev_addr);
    411	else if (ch->desc->dma_dir == DMA_DEV_TO_MEM)
    412		moxart_dma_set_params(ch, d->dev_addr, sg->addr);
    413
    414	moxart_set_transfer_params(ch, sg->len);
    415
    416	moxart_start_dma(ch);
    417}
    418
    419static void moxart_dma_start_desc(struct dma_chan *chan)
    420{
    421	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    422	struct virt_dma_desc *vd;
    423
    424	vd = vchan_next_desc(&ch->vc);
    425
    426	if (!vd) {
    427		ch->desc = NULL;
    428		return;
    429	}
    430
    431	list_del(&vd->node);
    432
    433	ch->desc = to_moxart_dma_desc(&vd->tx);
    434	ch->sgidx = 0;
    435
    436	moxart_dma_start_sg(ch, 0);
    437}
    438
    439static void moxart_issue_pending(struct dma_chan *chan)
    440{
    441	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    442	unsigned long flags;
    443
    444	spin_lock_irqsave(&ch->vc.lock, flags);
    445	if (vchan_issue_pending(&ch->vc) && !ch->desc)
    446		moxart_dma_start_desc(chan);
    447	spin_unlock_irqrestore(&ch->vc.lock, flags);
    448}
    449
    450static size_t moxart_dma_desc_size(struct moxart_desc *d,
    451				   unsigned int completed_sgs)
    452{
    453	unsigned int i;
    454	size_t size;
    455
    456	for (size = i = completed_sgs; i < d->sglen; i++)
    457		size += d->sg[i].len;
    458
    459	return size;
    460}
    461
    462static size_t moxart_dma_desc_size_in_flight(struct moxart_chan *ch)
    463{
    464	size_t size;
    465	unsigned int completed_cycles, cycles;
    466
    467	size = moxart_dma_desc_size(ch->desc, ch->sgidx);
    468	cycles = readl(ch->base + REG_OFF_CYCLES);
    469	completed_cycles = (ch->desc->dma_cycles - cycles);
    470	size -= completed_cycles << es_bytes[ch->desc->es];
    471
    472	dev_dbg(chan2dev(&ch->vc.chan), "%s: size=%zu\n", __func__, size);
    473
    474	return size;
    475}
    476
    477static enum dma_status moxart_tx_status(struct dma_chan *chan,
    478					dma_cookie_t cookie,
    479					struct dma_tx_state *txstate)
    480{
    481	struct moxart_chan *ch = to_moxart_dma_chan(chan);
    482	struct virt_dma_desc *vd;
    483	struct moxart_desc *d;
    484	enum dma_status ret;
    485	unsigned long flags;
    486
    487	/*
    488	 * dma_cookie_status() assigns initial residue value.
    489	 */
    490	ret = dma_cookie_status(chan, cookie, txstate);
    491
    492	spin_lock_irqsave(&ch->vc.lock, flags);
    493	vd = vchan_find_desc(&ch->vc, cookie);
    494	if (vd) {
    495		d = to_moxart_dma_desc(&vd->tx);
    496		txstate->residue = moxart_dma_desc_size(d, 0);
    497	} else if (ch->desc && ch->desc->vd.tx.cookie == cookie) {
    498		txstate->residue = moxart_dma_desc_size_in_flight(ch);
    499	}
    500	spin_unlock_irqrestore(&ch->vc.lock, flags);
    501
    502	if (ch->error)
    503		return DMA_ERROR;
    504
    505	return ret;
    506}
    507
    508static void moxart_dma_init(struct dma_device *dma, struct device *dev)
    509{
    510	dma->device_prep_slave_sg		= moxart_prep_slave_sg;
    511	dma->device_alloc_chan_resources	= moxart_alloc_chan_resources;
    512	dma->device_free_chan_resources		= moxart_free_chan_resources;
    513	dma->device_issue_pending		= moxart_issue_pending;
    514	dma->device_tx_status			= moxart_tx_status;
    515	dma->device_config			= moxart_slave_config;
    516	dma->device_terminate_all		= moxart_terminate_all;
    517	dma->dev				= dev;
    518
    519	INIT_LIST_HEAD(&dma->channels);
    520}
    521
    522static irqreturn_t moxart_dma_interrupt(int irq, void *devid)
    523{
    524	struct moxart_dmadev *mc = devid;
    525	struct moxart_chan *ch = &mc->slave_chans[0];
    526	unsigned int i;
    527	u32 ctrl;
    528
    529	dev_dbg(chan2dev(&ch->vc.chan), "%s\n", __func__);
    530
    531	for (i = 0; i < APB_DMA_MAX_CHANNEL; i++, ch++) {
    532		if (!ch->allocated)
    533			continue;
    534
    535		ctrl = readl(ch->base + REG_OFF_CTRL);
    536
    537		dev_dbg(chan2dev(&ch->vc.chan), "%s: ch=%p ch->base=%p ctrl=%x\n",
    538			__func__, ch, ch->base, ctrl);
    539
    540		if (ctrl & APB_DMA_FIN_INT_STS) {
    541			ctrl &= ~APB_DMA_FIN_INT_STS;
    542			if (ch->desc) {
    543				spin_lock(&ch->vc.lock);
    544				if (++ch->sgidx < ch->desc->sglen) {
    545					moxart_dma_start_sg(ch, ch->sgidx);
    546				} else {
    547					vchan_cookie_complete(&ch->desc->vd);
    548					moxart_dma_start_desc(&ch->vc.chan);
    549				}
    550				spin_unlock(&ch->vc.lock);
    551			}
    552		}
    553
    554		if (ctrl & APB_DMA_ERR_INT_STS) {
    555			ctrl &= ~APB_DMA_ERR_INT_STS;
    556			ch->error = 1;
    557		}
    558
    559		writel(ctrl, ch->base + REG_OFF_CTRL);
    560	}
    561
    562	return IRQ_HANDLED;
    563}
    564
    565static int moxart_probe(struct platform_device *pdev)
    566{
    567	struct device *dev = &pdev->dev;
    568	struct device_node *node = dev->of_node;
    569	struct resource *res;
    570	void __iomem *dma_base_addr;
    571	int ret, i;
    572	unsigned int irq;
    573	struct moxart_chan *ch;
    574	struct moxart_dmadev *mdc;
    575
    576	mdc = devm_kzalloc(dev, sizeof(*mdc), GFP_KERNEL);
    577	if (!mdc)
    578		return -ENOMEM;
    579
    580	irq = irq_of_parse_and_map(node, 0);
    581	if (!irq) {
    582		dev_err(dev, "no IRQ resource\n");
    583		return -EINVAL;
    584	}
    585
    586	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    587	dma_base_addr = devm_ioremap_resource(dev, res);
    588	if (IS_ERR(dma_base_addr))
    589		return PTR_ERR(dma_base_addr);
    590
    591	dma_cap_zero(mdc->dma_slave.cap_mask);
    592	dma_cap_set(DMA_SLAVE, mdc->dma_slave.cap_mask);
    593	dma_cap_set(DMA_PRIVATE, mdc->dma_slave.cap_mask);
    594
    595	moxart_dma_init(&mdc->dma_slave, dev);
    596
    597	ch = &mdc->slave_chans[0];
    598	for (i = 0; i < APB_DMA_MAX_CHANNEL; i++, ch++) {
    599		ch->ch_num = i;
    600		ch->base = dma_base_addr + i * REG_OFF_CHAN_SIZE;
    601		ch->allocated = 0;
    602
    603		ch->vc.desc_free = moxart_dma_desc_free;
    604		vchan_init(&ch->vc, &mdc->dma_slave);
    605
    606		dev_dbg(dev, "%s: chs[%d]: ch->ch_num=%u ch->base=%p\n",
    607			__func__, i, ch->ch_num, ch->base);
    608	}
    609
    610	platform_set_drvdata(pdev, mdc);
    611
    612	ret = devm_request_irq(dev, irq, moxart_dma_interrupt, 0,
    613			       "moxart-dma-engine", mdc);
    614	if (ret) {
    615		dev_err(dev, "devm_request_irq failed\n");
    616		return ret;
    617	}
    618	mdc->irq = irq;
    619
    620	ret = dma_async_device_register(&mdc->dma_slave);
    621	if (ret) {
    622		dev_err(dev, "dma_async_device_register failed\n");
    623		return ret;
    624	}
    625
    626	ret = of_dma_controller_register(node, moxart_of_xlate, mdc);
    627	if (ret) {
    628		dev_err(dev, "of_dma_controller_register failed\n");
    629		dma_async_device_unregister(&mdc->dma_slave);
    630		return ret;
    631	}
    632
    633	dev_dbg(dev, "%s: IRQ=%u\n", __func__, irq);
    634
    635	return 0;
    636}
    637
    638static int moxart_remove(struct platform_device *pdev)
    639{
    640	struct moxart_dmadev *m = platform_get_drvdata(pdev);
    641
    642	devm_free_irq(&pdev->dev, m->irq, m);
    643
    644	dma_async_device_unregister(&m->dma_slave);
    645
    646	if (pdev->dev.of_node)
    647		of_dma_controller_free(pdev->dev.of_node);
    648
    649	return 0;
    650}
    651
    652static const struct of_device_id moxart_dma_match[] = {
    653	{ .compatible = "moxa,moxart-dma" },
    654	{ }
    655};
    656MODULE_DEVICE_TABLE(of, moxart_dma_match);
    657
    658static struct platform_driver moxart_driver = {
    659	.probe	= moxart_probe,
    660	.remove	= moxart_remove,
    661	.driver = {
    662		.name		= "moxart-dma-engine",
    663		.of_match_table	= moxart_dma_match,
    664	},
    665};
    666
    667static int moxart_init(void)
    668{
    669	return platform_driver_register(&moxart_driver);
    670}
    671subsys_initcall(moxart_init);
    672
    673static void __exit moxart_exit(void)
    674{
    675	platform_driver_unregister(&moxart_driver);
    676}
    677module_exit(moxart_exit);
    678
    679MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");
    680MODULE_DESCRIPTION("MOXART DMA engine driver");
    681MODULE_LICENSE("GPL v2");