aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-05-30 12:25:05 -0400
committerVinod Koul <vinod.koul@intel.com>2013-07-05 02:10:52 -0400
commit25ce6c35fea0588c7a1b68e55d700c22d9e97ce0 (patch)
tree11b3054e16aaf08282f0c406137c30d0fe8bfd25 /drivers/dma
parentcdcb90ad48816f51fdb4e93b2a33fe6038ce0949 (diff)
MIPS: jz4740: Remove custom DMA API
Now that all users of the custom jz4740 DMA API have been converted to use the dmaengine API instead we can remove the custom API and move all the code talking to the hardware to the dmaengine driver. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/dma-jz4740.c258
1 files changed, 221 insertions, 37 deletions
diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c
index 3d424341d8fe..b0c0c8268d42 100644
--- a/drivers/dma/dma-jz4740.c
+++ b/drivers/dma/dma-jz4740.c
@@ -22,6 +22,8 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/irq.h>
26#include <linux/clk.h>
25 27
26#include <asm/mach-jz4740/dma.h> 28#include <asm/mach-jz4740/dma.h>
27 29
@@ -29,6 +31,76 @@
29 31
30#define JZ_DMA_NR_CHANS 6 32#define JZ_DMA_NR_CHANS 6
31 33
34#define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20)
35#define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20)
36#define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20)
37#define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20)
38#define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20)
39#define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20)
40#define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20)
41
42#define JZ_REG_DMA_CTRL 0x300
43#define JZ_REG_DMA_IRQ 0x304
44#define JZ_REG_DMA_DOORBELL 0x308
45#define JZ_REG_DMA_DOORBELL_SET 0x30C
46
47#define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31)
48#define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6)
49#define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4)
50#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3)
51#define JZ_DMA_STATUS_CTRL_HALT BIT(2)
52#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1)
53#define JZ_DMA_STATUS_CTRL_ENABLE BIT(0)
54
55#define JZ_DMA_CMD_SRC_INC BIT(23)
56#define JZ_DMA_CMD_DST_INC BIT(22)
57#define JZ_DMA_CMD_RDIL_MASK (0xf << 16)
58#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14)
59#define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12)
60#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8)
61#define JZ_DMA_CMD_BLOCK_MODE BIT(7)
62#define JZ_DMA_CMD_DESC_VALID BIT(4)
63#define JZ_DMA_CMD_DESC_VALID_MODE BIT(3)
64#define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2)
65#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1)
66#define JZ_DMA_CMD_LINK_ENABLE BIT(0)
67
68#define JZ_DMA_CMD_FLAGS_OFFSET 22
69#define JZ_DMA_CMD_RDIL_OFFSET 16
70#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
71#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
72#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
73#define JZ_DMA_CMD_MODE_OFFSET 7
74
75#define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8)
76#define JZ_DMA_CTRL_HALT BIT(3)
77#define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2)
78#define JZ_DMA_CTRL_ENABLE BIT(0)
79
80enum jz4740_dma_width {
81 JZ4740_DMA_WIDTH_32BIT = 0,
82 JZ4740_DMA_WIDTH_8BIT = 1,
83 JZ4740_DMA_WIDTH_16BIT = 2,
84};
85
86enum jz4740_dma_transfer_size {
87 JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0,
88 JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1,
89 JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2,
90 JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
91 JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
92};
93
94enum jz4740_dma_flags {
95 JZ4740_DMA_SRC_AUTOINC = 0x2,
96 JZ4740_DMA_DST_AUTOINC = 0x1,
97};
98
99enum jz4740_dma_mode {
100 JZ4740_DMA_MODE_SINGLE = 0,
101 JZ4740_DMA_MODE_BLOCK = 1,
102};
103
32struct jz4740_dma_sg { 104struct jz4740_dma_sg {
33 dma_addr_t addr; 105 dma_addr_t addr;
34 unsigned int len; 106 unsigned int len;
@@ -46,9 +118,10 @@ struct jz4740_dma_desc {
46 118
47struct jz4740_dmaengine_chan { 119struct jz4740_dmaengine_chan {
48 struct virt_dma_chan vchan; 120 struct virt_dma_chan vchan;
49 struct jz4740_dma_chan *jz_chan; 121 unsigned int id;
50 122
51 dma_addr_t fifo_addr; 123 dma_addr_t fifo_addr;
124 unsigned int transfer_shift;
52 125
53 struct jz4740_dma_desc *desc; 126 struct jz4740_dma_desc *desc;
54 unsigned int next_sg; 127 unsigned int next_sg;
@@ -56,10 +129,19 @@ struct jz4740_dmaengine_chan {
56 129
57struct jz4740_dma_dev { 130struct jz4740_dma_dev {
58 struct dma_device ddev; 131 struct dma_device ddev;
132 void __iomem *base;
133 struct clk *clk;
59 134
60 struct jz4740_dmaengine_chan chan[JZ_DMA_NR_CHANS]; 135 struct jz4740_dmaengine_chan chan[JZ_DMA_NR_CHANS];
61}; 136};
62 137
138static struct jz4740_dma_dev *jz4740_dma_chan_get_dev(
139 struct jz4740_dmaengine_chan *chan)
140{
141 return container_of(chan->vchan.chan.device, struct jz4740_dma_dev,
142 ddev);
143}
144
63static struct jz4740_dmaengine_chan *to_jz4740_dma_chan(struct dma_chan *c) 145static struct jz4740_dmaengine_chan *to_jz4740_dma_chan(struct dma_chan *c)
64{ 146{
65 return container_of(c, struct jz4740_dmaengine_chan, vchan.chan); 147 return container_of(c, struct jz4740_dmaengine_chan, vchan.chan);
@@ -70,6 +152,29 @@ static struct jz4740_dma_desc *to_jz4740_dma_desc(struct virt_dma_desc *vdesc)
70 return container_of(vdesc, struct jz4740_dma_desc, vdesc); 152 return container_of(vdesc, struct jz4740_dma_desc, vdesc);
71} 153}
72 154
155static inline uint32_t jz4740_dma_read(struct jz4740_dma_dev *dmadev,
156 unsigned int reg)
157{
158 return readl(dmadev->base + reg);
159}
160
161static inline void jz4740_dma_write(struct jz4740_dma_dev *dmadev,
162 unsigned reg, uint32_t val)
163{
164 writel(val, dmadev->base + reg);
165}
166
167static inline void jz4740_dma_write_mask(struct jz4740_dma_dev *dmadev,
168 unsigned int reg, uint32_t val, uint32_t mask)
169{
170 uint32_t tmp;
171
172 tmp = jz4740_dma_read(dmadev, reg);
173 tmp &= ~mask;
174 tmp |= val;
175 jz4740_dma_write(dmadev, reg, tmp);
176}
177
73static struct jz4740_dma_desc *jz4740_dma_alloc_desc(unsigned int num_sgs) 178static struct jz4740_dma_desc *jz4740_dma_alloc_desc(unsigned int num_sgs)
74{ 179{
75 return kzalloc(sizeof(struct jz4740_dma_desc) + 180 return kzalloc(sizeof(struct jz4740_dma_desc) +
@@ -108,30 +213,60 @@ static int jz4740_dma_slave_config(struct dma_chan *c,
108 const struct dma_slave_config *config) 213 const struct dma_slave_config *config)
109{ 214{
110 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 215 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
111 struct jz4740_dma_config jzcfg; 216 struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
217 enum jz4740_dma_width src_width;
218 enum jz4740_dma_width dst_width;
219 enum jz4740_dma_transfer_size transfer_size;
220 enum jz4740_dma_flags flags;
221 uint32_t cmd;
112 222
113 switch (config->direction) { 223 switch (config->direction) {
114 case DMA_MEM_TO_DEV: 224 case DMA_MEM_TO_DEV:
115 jzcfg.flags = JZ4740_DMA_SRC_AUTOINC; 225 flags = JZ4740_DMA_SRC_AUTOINC;
116 jzcfg.transfer_size = jz4740_dma_maxburst(config->dst_maxburst); 226 transfer_size = jz4740_dma_maxburst(config->dst_maxburst);
117 chan->fifo_addr = config->dst_addr; 227 chan->fifo_addr = config->dst_addr;
118 break; 228 break;
119 case DMA_DEV_TO_MEM: 229 case DMA_DEV_TO_MEM:
120 jzcfg.flags = JZ4740_DMA_DST_AUTOINC; 230 flags = JZ4740_DMA_DST_AUTOINC;
121 jzcfg.transfer_size = jz4740_dma_maxburst(config->src_maxburst); 231 transfer_size = jz4740_dma_maxburst(config->src_maxburst);
122 chan->fifo_addr = config->src_addr; 232 chan->fifo_addr = config->src_addr;
123 break; 233 break;
124 default: 234 default:
125 return -EINVAL; 235 return -EINVAL;
126 } 236 }
127 237
238 src_width = jz4740_dma_width(config->src_addr_width);
239 dst_width = jz4740_dma_width(config->dst_addr_width);
240
241 switch (transfer_size) {
242 case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
243 chan->transfer_shift = 1;
244 break;
245 case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
246 chan->transfer_shift = 2;
247 break;
248 case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
249 chan->transfer_shift = 4;
250 break;
251 case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
252 chan->transfer_shift = 5;
253 break;
254 default:
255 chan->transfer_shift = 0;
256 break;
257 }
128 258
129 jzcfg.src_width = jz4740_dma_width(config->src_addr_width); 259 cmd = flags << JZ_DMA_CMD_FLAGS_OFFSET;
130 jzcfg.dst_width = jz4740_dma_width(config->dst_addr_width); 260 cmd |= src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
131 jzcfg.mode = JZ4740_DMA_MODE_SINGLE; 261 cmd |= dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
132 jzcfg.request_type = config->slave_id; 262 cmd |= transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
263 cmd |= JZ4740_DMA_MODE_SINGLE << JZ_DMA_CMD_MODE_OFFSET;
264 cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
133 265
134 jz4740_dma_configure(chan->jz_chan, &jzcfg); 266 jz4740_dma_write(dmadev, JZ_REG_DMA_CMD(chan->id), cmd);
267 jz4740_dma_write(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0);
268 jz4740_dma_write(dmadev, JZ_REG_DMA_REQ_TYPE(chan->id),
269 config->slave_id);
135 270
136 return 0; 271 return 0;
137} 272}
@@ -139,11 +274,13 @@ static int jz4740_dma_slave_config(struct dma_chan *c,
139static int jz4740_dma_terminate_all(struct dma_chan *c) 274static int jz4740_dma_terminate_all(struct dma_chan *c)
140{ 275{
141 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 276 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
277 struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
142 unsigned long flags; 278 unsigned long flags;
143 LIST_HEAD(head); 279 LIST_HEAD(head);
144 280
145 spin_lock_irqsave(&chan->vchan.lock, flags); 281 spin_lock_irqsave(&chan->vchan.lock, flags);
146 jz4740_dma_disable(chan->jz_chan); 282 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0,
283 JZ_DMA_STATUS_CTRL_ENABLE);
147 chan->desc = NULL; 284 chan->desc = NULL;
148 vchan_get_all_descriptors(&chan->vchan, &head); 285 vchan_get_all_descriptors(&chan->vchan, &head);
149 spin_unlock_irqrestore(&chan->vchan.lock, flags); 286 spin_unlock_irqrestore(&chan->vchan.lock, flags);
@@ -170,11 +307,13 @@ static int jz4740_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
170 307
171static int jz4740_dma_start_transfer(struct jz4740_dmaengine_chan *chan) 308static int jz4740_dma_start_transfer(struct jz4740_dmaengine_chan *chan)
172{ 309{
310 struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
173 dma_addr_t src_addr, dst_addr; 311 dma_addr_t src_addr, dst_addr;
174 struct virt_dma_desc *vdesc; 312 struct virt_dma_desc *vdesc;
175 struct jz4740_dma_sg *sg; 313 struct jz4740_dma_sg *sg;
176 314
177 jz4740_dma_disable(chan->jz_chan); 315 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0,
316 JZ_DMA_STATUS_CTRL_ENABLE);
178 317
179 if (!chan->desc) { 318 if (!chan->desc) {
180 vdesc = vchan_next_desc(&chan->vchan); 319 vdesc = vchan_next_desc(&chan->vchan);
@@ -196,22 +335,27 @@ static int jz4740_dma_start_transfer(struct jz4740_dmaengine_chan *chan)
196 src_addr = chan->fifo_addr; 335 src_addr = chan->fifo_addr;
197 dst_addr = sg->addr; 336 dst_addr = sg->addr;
198 } 337 }
199 jz4740_dma_set_src_addr(chan->jz_chan, src_addr); 338 jz4740_dma_write(dmadev, JZ_REG_DMA_SRC_ADDR(chan->id), src_addr);
200 jz4740_dma_set_dst_addr(chan->jz_chan, dst_addr); 339 jz4740_dma_write(dmadev, JZ_REG_DMA_DST_ADDR(chan->id), dst_addr);
201 jz4740_dma_set_transfer_count(chan->jz_chan, sg->len); 340 jz4740_dma_write(dmadev, JZ_REG_DMA_TRANSFER_COUNT(chan->id),
341 sg->len >> chan->transfer_shift);
202 342
203 chan->next_sg++; 343 chan->next_sg++;
204 344
205 jz4740_dma_enable(chan->jz_chan); 345 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id),
346 JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE,
347 JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC |
348 JZ_DMA_STATUS_CTRL_ENABLE);
349
350 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_CTRL,
351 JZ_DMA_CTRL_ENABLE,
352 JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE);
206 353
207 return 0; 354 return 0;
208} 355}
209 356
210static void jz4740_dma_complete_cb(struct jz4740_dma_chan *jz_chan, int error, 357static void jz4740_dma_chan_irq(struct jz4740_dmaengine_chan *chan)
211 void *devid)
212{ 358{
213 struct jz4740_dmaengine_chan *chan = devid;
214
215 spin_lock(&chan->vchan.lock); 359 spin_lock(&chan->vchan.lock);
216 if (chan->desc) { 360 if (chan->desc) {
217 if (chan->desc && chan->desc->cyclic) { 361 if (chan->desc && chan->desc->cyclic) {
@@ -227,6 +371,28 @@ static void jz4740_dma_complete_cb(struct jz4740_dma_chan *jz_chan, int error,
227 spin_unlock(&chan->vchan.lock); 371 spin_unlock(&chan->vchan.lock);
228} 372}
229 373
374static irqreturn_t jz4740_dma_irq(int irq, void *devid)
375{
376 struct jz4740_dma_dev *dmadev = devid;
377 uint32_t irq_status;
378 unsigned int i;
379
380 irq_status = readl(dmadev->base + JZ_REG_DMA_IRQ);
381
382 for (i = 0; i < 6; ++i) {
383 if (irq_status & (1 << i)) {
384 jz4740_dma_write_mask(dmadev,
385 JZ_REG_DMA_STATUS_CTRL(i), 0,
386 JZ_DMA_STATUS_CTRL_ENABLE |
387 JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
388
389 jz4740_dma_chan_irq(&dmadev->chan[i]);
390 }
391 }
392
393 return IRQ_HANDLED;
394}
395
230static void jz4740_dma_issue_pending(struct dma_chan *c) 396static void jz4740_dma_issue_pending(struct dma_chan *c)
231{ 397{
232 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 398 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
@@ -298,7 +464,8 @@ static struct dma_async_tx_descriptor *jz4740_dma_prep_dma_cyclic(
298static size_t jz4740_dma_desc_residue(struct jz4740_dmaengine_chan *chan, 464static size_t jz4740_dma_desc_residue(struct jz4740_dmaengine_chan *chan,
299 struct jz4740_dma_desc *desc, unsigned int next_sg) 465 struct jz4740_dma_desc *desc, unsigned int next_sg)
300{ 466{
301 size_t residue = 0; 467 struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
468 unsigned int residue, count;
302 unsigned int i; 469 unsigned int i;
303 470
304 residue = 0; 471 residue = 0;
@@ -306,8 +473,11 @@ static size_t jz4740_dma_desc_residue(struct jz4740_dmaengine_chan *chan,
306 for (i = next_sg; i < desc->num_sgs; i++) 473 for (i = next_sg; i < desc->num_sgs; i++)
307 residue += desc->sg[i].len; 474 residue += desc->sg[i].len;
308 475
309 if (next_sg != 0) 476 if (next_sg != 0) {
310 residue += jz4740_dma_get_residue(chan->jz_chan); 477 count = jz4740_dma_read(dmadev,
478 JZ_REG_DMA_TRANSFER_COUNT(chan->id));
479 residue += count << chan->transfer_shift;
480 }
311 481
312 return residue; 482 return residue;
313} 483}
@@ -342,24 +512,12 @@ static enum dma_status jz4740_dma_tx_status(struct dma_chan *c,
342 512
343static int jz4740_dma_alloc_chan_resources(struct dma_chan *c) 513static int jz4740_dma_alloc_chan_resources(struct dma_chan *c)
344{ 514{
345 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
346
347 chan->jz_chan = jz4740_dma_request(chan, NULL);
348 if (!chan->jz_chan)
349 return -EBUSY;
350
351 jz4740_dma_set_complete_cb(chan->jz_chan, jz4740_dma_complete_cb);
352
353 return 0; 515 return 0;
354} 516}
355 517
356static void jz4740_dma_free_chan_resources(struct dma_chan *c) 518static void jz4740_dma_free_chan_resources(struct dma_chan *c)
357{ 519{
358 struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 520 vchan_free_chan_resources(to_virt_chan(c));
359
360 vchan_free_chan_resources(&chan->vchan);
361 jz4740_dma_free(chan->jz_chan);
362 chan->jz_chan = NULL;
363} 521}
364 522
365static void jz4740_dma_desc_free(struct virt_dma_desc *vdesc) 523static void jz4740_dma_desc_free(struct virt_dma_desc *vdesc)
@@ -373,7 +531,9 @@ static int jz4740_dma_probe(struct platform_device *pdev)
373 struct jz4740_dma_dev *dmadev; 531 struct jz4740_dma_dev *dmadev;
374 struct dma_device *dd; 532 struct dma_device *dd;
375 unsigned int i; 533 unsigned int i;
534 struct resource *res;
376 int ret; 535 int ret;
536 int irq;
377 537
378 dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL); 538 dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL);
379 if (!dmadev) 539 if (!dmadev)
@@ -381,6 +541,17 @@ static int jz4740_dma_probe(struct platform_device *pdev)
381 541
382 dd = &dmadev->ddev; 542 dd = &dmadev->ddev;
383 543
544 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
545 dmadev->base = devm_ioremap_resource(&pdev->dev, res);
546 if (IS_ERR(dmadev->base))
547 return PTR_ERR(dmadev->base);
548
549 dmadev->clk = clk_get(&pdev->dev, "dma");
550 if (IS_ERR(dmadev->clk))
551 return PTR_ERR(dmadev->clk);
552
553 clk_prepare_enable(dmadev->clk);
554
384 dma_cap_set(DMA_SLAVE, dd->cap_mask); 555 dma_cap_set(DMA_SLAVE, dd->cap_mask);
385 dma_cap_set(DMA_CYCLIC, dd->cap_mask); 556 dma_cap_set(DMA_CYCLIC, dd->cap_mask);
386 dd->device_alloc_chan_resources = jz4740_dma_alloc_chan_resources; 557 dd->device_alloc_chan_resources = jz4740_dma_alloc_chan_resources;
@@ -396,6 +567,7 @@ static int jz4740_dma_probe(struct platform_device *pdev)
396 567
397 for (i = 0; i < dd->chancnt; i++) { 568 for (i = 0; i < dd->chancnt; i++) {
398 chan = &dmadev->chan[i]; 569 chan = &dmadev->chan[i];
570 chan->id = i;
399 chan->vchan.desc_free = jz4740_dma_desc_free; 571 chan->vchan.desc_free = jz4740_dma_desc_free;
400 vchan_init(&chan->vchan, dd); 572 vchan_init(&chan->vchan, dd);
401 } 573 }
@@ -404,16 +576,28 @@ static int jz4740_dma_probe(struct platform_device *pdev)
404 if (ret) 576 if (ret)
405 return ret; 577 return ret;
406 578
579 irq = platform_get_irq(pdev, 0);
580 ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev);
581 if (ret)
582 goto err_unregister;
583
407 platform_set_drvdata(pdev, dmadev); 584 platform_set_drvdata(pdev, dmadev);
408 585
409 return 0; 586 return 0;
587
588err_unregister:
589 dma_async_device_unregister(dd);
590 return ret;
410} 591}
411 592
412static int jz4740_dma_remove(struct platform_device *pdev) 593static int jz4740_dma_remove(struct platform_device *pdev)
413{ 594{
414 struct jz4740_dma_dev *dmadev = platform_get_drvdata(pdev); 595 struct jz4740_dma_dev *dmadev = platform_get_drvdata(pdev);
596 int irq = platform_get_irq(pdev, 0);
415 597
598 free_irq(irq, dmadev);
416 dma_async_device_unregister(&dmadev->ddev); 599 dma_async_device_unregister(&dmadev->ddev);
600 clk_disable_unprepare(dmadev->clk);
417 601
418 return 0; 602 return 0;
419} 603}