1 /* linux/arch/arm/plat-s3c64xx/dma.c
2  *
3  * Copyright 2009 Openmoko, Inc.
4  * Copyright 2009 Simtec Electronics
5  *	Ben Dooks <ben@simtec.co.uk>
6  *	http://armlinux.simtec.co.uk/
7  *
8  * S3C64XX DMA core
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13 */
14 
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/interrupt.h>
18 #include <linux/dmapool.h>
19 #include <linux/sysdev.h>
20 #include <linux/errno.h>
21 #include <linux/slab.h>
22 #include <linux/delay.h>
23 #include <linux/clk.h>
24 #include <linux/err.h>
25 #include <linux/io.h>
26 
27 #include <mach/dma.h>
28 #include <mach/map.h>
29 #include <mach/irqs.h>
30 
31 #include <mach/regs-sys.h>
32 
33 #include <asm/hardware/pl080.h>
34 
35 /* dma channel state information */
36 
37 struct s3c64xx_dmac {
38 	struct sys_device	 sysdev;
39 	struct clk		*clk;
40 	void __iomem		*regs;
41 	struct s3c2410_dma_chan *channels;
42 	enum dma_ch		 chanbase;
43 };
44 
45 /* pool to provide LLI buffers */
46 static struct dma_pool *dma_pool;
47 
48 /* Debug configuration and code */
49 
50 static unsigned char debug_show_buffs = 0;
51 
dbg_showchan(struct s3c2410_dma_chan * chan)52 static void dbg_showchan(struct s3c2410_dma_chan *chan)
53 {
54 	pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
55 		 chan->number,
56 		 readl(chan->regs + PL080_CH_SRC_ADDR),
57 		 readl(chan->regs + PL080_CH_DST_ADDR),
58 		 readl(chan->regs + PL080_CH_LLI),
59 		 readl(chan->regs + PL080_CH_CONTROL),
60 		 readl(chan->regs + PL080S_CH_CONTROL2),
61 		 readl(chan->regs + PL080S_CH_CONFIG));
62 }
63 
show_lli(struct pl080s_lli * lli)64 static void show_lli(struct pl080s_lli *lli)
65 {
66 	pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
67 		 lli, lli->src_addr, lli->dst_addr, lli->next_lli,
68 		 lli->control0, lli->control1);
69 }
70 
dbg_showbuffs(struct s3c2410_dma_chan * chan)71 static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
72 {
73 	struct s3c64xx_dma_buff *ptr;
74 	struct s3c64xx_dma_buff *end;
75 
76 	pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
77 		 chan->number, chan->next, chan->curr, chan->end);
78 
79 	ptr = chan->next;
80 	end = chan->end;
81 
82 	if (debug_show_buffs) {
83 		for (; ptr != NULL; ptr = ptr->next) {
84 			pr_debug("DMA%d: %08x ",
85 				 chan->number, ptr->lli_dma);
86 			show_lli(ptr->lli);
87 		}
88 	}
89 }
90 
91 /* End of Debug */
92 
s3c64xx_dma_map_channel(unsigned int channel)93 static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
94 {
95 	struct s3c2410_dma_chan *chan;
96 	unsigned int start, offs;
97 
98 	start = 0;
99 
100 	if (channel >= DMACH_PCM1_TX)
101 		start = 8;
102 
103 	for (offs = 0; offs < 8; offs++) {
104 		chan = &s3c2410_chans[start + offs];
105 		if (!chan->in_use)
106 			goto found;
107 	}
108 
109 	return NULL;
110 
111 found:
112 	s3c_dma_chan_map[channel] = chan;
113 	return chan;
114 }
115 
s3c2410_dma_config(unsigned int channel,int xferunit)116 int s3c2410_dma_config(unsigned int channel, int xferunit)
117 {
118 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
119 
120 	if (chan == NULL)
121 		return -EINVAL;
122 
123 	switch (xferunit) {
124 	case 1:
125 		chan->hw_width = 0;
126 		break;
127 	case 2:
128 		chan->hw_width = 1;
129 		break;
130 	case 4:
131 		chan->hw_width = 2;
132 		break;
133 	default:
134 		printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
135 		return -EINVAL;
136 	}
137 
138 	return 0;
139 }
140 EXPORT_SYMBOL(s3c2410_dma_config);
141 
s3c64xx_dma_fill_lli(struct s3c2410_dma_chan * chan,struct pl080s_lli * lli,dma_addr_t data,int size)142 static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
143 				 struct pl080s_lli *lli,
144 				 dma_addr_t data, int size)
145 {
146 	dma_addr_t src, dst;
147 	u32 control0, control1;
148 
149 	switch (chan->source) {
150 	case S3C2410_DMASRC_HW:
151 		src = chan->dev_addr;
152 		dst = data;
153 		control0 = PL080_CONTROL_SRC_AHB2;
154 		control0 |= PL080_CONTROL_DST_INCR;
155 		break;
156 
157 	case S3C2410_DMASRC_MEM:
158 		src = data;
159 		dst = chan->dev_addr;
160 		control0 = PL080_CONTROL_DST_AHB2;
161 		control0 |= PL080_CONTROL_SRC_INCR;
162 		break;
163 	default:
164 		BUG();
165 	}
166 
167 	/* note, we do not currently setup any of the burst controls */
168 
169 	control1 = size >> chan->hw_width;	/* size in no of xfers */
170 	control0 |= PL080_CONTROL_PROT_SYS;	/* always in priv. mode */
171 	control0 |= PL080_CONTROL_TC_IRQ_EN;	/* always fire IRQ */
172 	control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
173 	control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
174 
175 	lli->src_addr = src;
176 	lli->dst_addr = dst;
177 	lli->next_lli = 0;
178 	lli->control0 = control0;
179 	lli->control1 = control1;
180 }
181 
s3c64xx_lli_to_regs(struct s3c2410_dma_chan * chan,struct pl080s_lli * lli)182 static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
183 				struct pl080s_lli *lli)
184 {
185 	void __iomem *regs = chan->regs;
186 
187 	pr_debug("%s: LLI %p => regs\n", __func__, lli);
188 	show_lli(lli);
189 
190 	writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
191 	writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
192 	writel(lli->next_lli, regs + PL080_CH_LLI);
193 	writel(lli->control0, regs + PL080_CH_CONTROL);
194 	writel(lli->control1, regs + PL080S_CH_CONTROL2);
195 }
196 
s3c64xx_dma_start(struct s3c2410_dma_chan * chan)197 static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
198 {
199 	struct s3c64xx_dmac *dmac = chan->dmac;
200 	u32 config;
201 	u32 bit = chan->bit;
202 
203 	dbg_showchan(chan);
204 
205 	pr_debug("%s: clearing interrupts\n", __func__);
206 
207 	/* clear interrupts */
208 	writel(bit, dmac->regs + PL080_TC_CLEAR);
209 	writel(bit, dmac->regs + PL080_ERR_CLEAR);
210 
211 	pr_debug("%s: starting channel\n", __func__);
212 
213 	config = readl(chan->regs + PL080S_CH_CONFIG);
214 	config |= PL080_CONFIG_ENABLE;
215 	config &= ~PL080_CONFIG_HALT;
216 
217 	pr_debug("%s: writing config %08x\n", __func__, config);
218 	writel(config, chan->regs + PL080S_CH_CONFIG);
219 
220 	return 0;
221 }
222 
s3c64xx_dma_stop(struct s3c2410_dma_chan * chan)223 static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
224 {
225 	u32 config;
226 	int timeout;
227 
228 	pr_debug("%s: stopping channel\n", __func__);
229 
230 	dbg_showchan(chan);
231 
232 	config = readl(chan->regs + PL080S_CH_CONFIG);
233 	config |= PL080_CONFIG_HALT;
234 	writel(config, chan->regs + PL080S_CH_CONFIG);
235 
236 	timeout = 1000;
237 	do {
238 		config = readl(chan->regs + PL080S_CH_CONFIG);
239 		pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
240 		if (config & PL080_CONFIG_ACTIVE)
241 			udelay(10);
242 		else
243 			break;
244 		} while (--timeout > 0);
245 
246 	if (config & PL080_CONFIG_ACTIVE) {
247 		printk(KERN_ERR "%s: channel still active\n", __func__);
248 		return -EFAULT;
249 	}
250 
251 	config = readl(chan->regs + PL080S_CH_CONFIG);
252 	config &= ~PL080_CONFIG_ENABLE;
253 	writel(config, chan->regs + PL080S_CH_CONFIG);
254 
255 	return 0;
256 }
257 
s3c64xx_dma_bufffdone(struct s3c2410_dma_chan * chan,struct s3c64xx_dma_buff * buf,enum s3c2410_dma_buffresult result)258 static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
259 					 struct s3c64xx_dma_buff *buf,
260 					 enum s3c2410_dma_buffresult result)
261 {
262 	if (chan->callback_fn != NULL)
263 		(chan->callback_fn)(chan, buf->pw, 0, result);
264 }
265 
s3c64xx_dma_freebuff(struct s3c64xx_dma_buff * buff)266 static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
267 {
268 	dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
269 	kfree(buff);
270 }
271 
s3c64xx_dma_flush(struct s3c2410_dma_chan * chan)272 static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
273 {
274 	struct s3c64xx_dma_buff *buff, *next;
275 	u32 config;
276 
277 	dbg_showchan(chan);
278 
279 	pr_debug("%s: flushing channel\n", __func__);
280 
281 	config = readl(chan->regs + PL080S_CH_CONFIG);
282 	config &= ~PL080_CONFIG_ENABLE;
283 	writel(config, chan->regs + PL080S_CH_CONFIG);
284 
285 	/* dump all the buffers associated with this channel */
286 
287 	for (buff = chan->curr; buff != NULL; buff = next) {
288 		next = buff->next;
289 		pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
290 
291 		s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
292 		s3c64xx_dma_freebuff(buff);
293 	}
294 
295 	chan->curr = chan->next = chan->end = NULL;
296 
297 	return 0;
298 }
299 
s3c2410_dma_ctrl(unsigned int channel,enum s3c2410_chan_op op)300 int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
301 {
302 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
303 
304 	WARN_ON(!chan);
305 	if (!chan)
306 		return -EINVAL;
307 
308 	switch (op) {
309 	case S3C2410_DMAOP_START:
310 		return s3c64xx_dma_start(chan);
311 
312 	case S3C2410_DMAOP_STOP:
313 		return s3c64xx_dma_stop(chan);
314 
315 	case S3C2410_DMAOP_FLUSH:
316 		return s3c64xx_dma_flush(chan);
317 
318 	/* believe PAUSE/RESUME are no-ops */
319 	case S3C2410_DMAOP_PAUSE:
320 	case S3C2410_DMAOP_RESUME:
321 	case S3C2410_DMAOP_STARTED:
322 	case S3C2410_DMAOP_TIMEOUT:
323 		return 0;
324 	}
325 
326 	return -ENOENT;
327 }
328 EXPORT_SYMBOL(s3c2410_dma_ctrl);
329 
330 /* s3c2410_dma_enque
331  *
332  */
333 
s3c2410_dma_enqueue(unsigned int channel,void * id,dma_addr_t data,int size)334 int s3c2410_dma_enqueue(unsigned int channel, void *id,
335 			dma_addr_t data, int size)
336 {
337 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
338 	struct s3c64xx_dma_buff *next;
339 	struct s3c64xx_dma_buff *buff;
340 	struct pl080s_lli *lli;
341 	unsigned long flags;
342 	int ret;
343 
344 	WARN_ON(!chan);
345 	if (!chan)
346 		return -EINVAL;
347 
348 	buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
349 	if (!buff) {
350 		printk(KERN_ERR "%s: no memory for buffer\n", __func__);
351 		return -ENOMEM;
352 	}
353 
354 	lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
355 	if (!lli) {
356 		printk(KERN_ERR "%s: no memory for lli\n", __func__);
357 		ret = -ENOMEM;
358 		goto err_buff;
359 	}
360 
361 	pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
362 		 __func__, buff, data, lli, (u32)buff->lli_dma, size);
363 
364 	buff->lli = lli;
365 	buff->pw = id;
366 
367 	s3c64xx_dma_fill_lli(chan, lli, data, size);
368 
369 	local_irq_save(flags);
370 
371 	if ((next = chan->next) != NULL) {
372 		struct s3c64xx_dma_buff *end = chan->end;
373 		struct pl080s_lli *endlli = end->lli;
374 
375 		pr_debug("enquing onto channel\n");
376 
377 		end->next = buff;
378 		endlli->next_lli = buff->lli_dma;
379 
380 		if (chan->flags & S3C2410_DMAF_CIRCULAR) {
381 			struct s3c64xx_dma_buff *curr = chan->curr;
382 			lli->next_lli = curr->lli_dma;
383 		}
384 
385 		if (next == chan->curr) {
386 			writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
387 			chan->next = buff;
388 		}
389 
390 		show_lli(endlli);
391 		chan->end = buff;
392 	} else {
393 		pr_debug("enquing onto empty channel\n");
394 
395 		chan->curr = buff;
396 		chan->next = buff;
397 		chan->end = buff;
398 
399 		s3c64xx_lli_to_regs(chan, lli);
400 	}
401 
402 	local_irq_restore(flags);
403 
404 	show_lli(lli);
405 
406 	dbg_showchan(chan);
407 	dbg_showbuffs(chan);
408 	return 0;
409 
410 err_buff:
411 	kfree(buff);
412 	return ret;
413 }
414 
415 EXPORT_SYMBOL(s3c2410_dma_enqueue);
416 
417 
s3c2410_dma_devconfig(unsigned int channel,enum s3c2410_dmasrc source,unsigned long devaddr)418 int s3c2410_dma_devconfig(unsigned int channel,
419 			  enum s3c2410_dmasrc source,
420 			  unsigned long devaddr)
421 {
422 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
423 	u32 peripheral;
424 	u32 config = 0;
425 
426 	pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
427 		 __func__, channel, source, devaddr, chan);
428 
429 	WARN_ON(!chan);
430 	if (!chan)
431 		return -EINVAL;
432 
433 	peripheral = (chan->peripheral & 0xf);
434 	chan->source = source;
435 	chan->dev_addr = devaddr;
436 
437 	pr_debug("%s: peripheral %d\n", __func__, peripheral);
438 
439 	switch (source) {
440 	case S3C2410_DMASRC_HW:
441 		config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
442 		config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
443 		break;
444 	case S3C2410_DMASRC_MEM:
445 		config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
446 		config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
447 		break;
448 	default:
449 		printk(KERN_ERR "%s: bad source\n", __func__);
450 		return -EINVAL;
451 	}
452 
453 	/* allow TC and ERR interrupts */
454 	config |= PL080_CONFIG_TC_IRQ_MASK;
455 	config |= PL080_CONFIG_ERR_IRQ_MASK;
456 
457 	pr_debug("%s: config %08x\n", __func__, config);
458 
459 	writel(config, chan->regs + PL080S_CH_CONFIG);
460 
461 	return 0;
462 }
463 EXPORT_SYMBOL(s3c2410_dma_devconfig);
464 
465 
s3c2410_dma_getposition(unsigned int channel,dma_addr_t * src,dma_addr_t * dst)466 int s3c2410_dma_getposition(unsigned int channel,
467 			    dma_addr_t *src, dma_addr_t *dst)
468 {
469 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
470 
471 	WARN_ON(!chan);
472 	if (!chan)
473 		return -EINVAL;
474 
475 	if (src != NULL)
476 		*src = readl(chan->regs + PL080_CH_SRC_ADDR);
477 
478 	if (dst != NULL)
479 		*dst = readl(chan->regs + PL080_CH_DST_ADDR);
480 
481 	return 0;
482 }
483 EXPORT_SYMBOL(s3c2410_dma_getposition);
484 
485 /* s3c2410_request_dma
486  *
487  * get control of an dma channel
488 */
489 
s3c2410_dma_request(unsigned int channel,struct s3c2410_dma_client * client,void * dev)490 int s3c2410_dma_request(unsigned int channel,
491 			struct s3c2410_dma_client *client,
492 			void *dev)
493 {
494 	struct s3c2410_dma_chan *chan;
495 	unsigned long flags;
496 
497 	pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
498 		 channel, client->name, dev);
499 
500 	local_irq_save(flags);
501 
502 	chan = s3c64xx_dma_map_channel(channel);
503 	if (chan == NULL) {
504 		local_irq_restore(flags);
505 		return -EBUSY;
506 	}
507 
508 	dbg_showchan(chan);
509 
510 	chan->client = client;
511 	chan->in_use = 1;
512 	chan->peripheral = channel;
513 
514 	local_irq_restore(flags);
515 
516 	/* need to setup */
517 
518 	pr_debug("%s: channel initialised, %p\n", __func__, chan);
519 
520 	return chan->number | DMACH_LOW_LEVEL;
521 }
522 
523 EXPORT_SYMBOL(s3c2410_dma_request);
524 
525 /* s3c2410_dma_free
526  *
527  * release the given channel back to the system, will stop and flush
528  * any outstanding transfers, and ensure the channel is ready for the
529  * next claimant.
530  *
531  * Note, although a warning is currently printed if the freeing client
532  * info is not the same as the registrant's client info, the free is still
533  * allowed to go through.
534 */
535 
s3c2410_dma_free(unsigned int channel,struct s3c2410_dma_client * client)536 int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
537 {
538 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
539 	unsigned long flags;
540 
541 	if (chan == NULL)
542 		return -EINVAL;
543 
544 	local_irq_save(flags);
545 
546 	if (chan->client != client) {
547 		printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
548 		       channel, chan->client, client);
549 	}
550 
551 	/* sort out stopping and freeing the channel */
552 
553 
554 	chan->client = NULL;
555 	chan->in_use = 0;
556 
557 	if (!(channel & DMACH_LOW_LEVEL))
558 		s3c_dma_chan_map[channel] = NULL;
559 
560 	local_irq_restore(flags);
561 
562 	return 0;
563 }
564 
565 EXPORT_SYMBOL(s3c2410_dma_free);
566 
s3c64xx_dma_irq(int irq,void * pw)567 static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
568 {
569 	struct s3c64xx_dmac *dmac = pw;
570 	struct s3c2410_dma_chan *chan;
571 	enum s3c2410_dma_buffresult res;
572 	u32 tcstat, errstat;
573 	u32 bit;
574 	int offs;
575 
576 	tcstat = readl(dmac->regs + PL080_TC_STATUS);
577 	errstat = readl(dmac->regs + PL080_ERR_STATUS);
578 
579 	for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
580 		struct s3c64xx_dma_buff *buff;
581 
582 		if (!(errstat & bit) && !(tcstat & bit))
583 			continue;
584 
585 		chan = dmac->channels + offs;
586 		res = S3C2410_RES_ERR;
587 
588 		if (tcstat & bit) {
589 			writel(bit, dmac->regs + PL080_TC_CLEAR);
590 			res = S3C2410_RES_OK;
591 		}
592 
593 		if (errstat & bit)
594 			writel(bit, dmac->regs + PL080_ERR_CLEAR);
595 
596 		/* 'next' points to the buffer that is next to the
597 		 * currently active buffer.
598 		 * For CIRCULAR queues, 'next' will be same as 'curr'
599 		 * when 'end' is the active buffer.
600 		 */
601 		buff = chan->curr;
602 		while (buff && buff != chan->next
603 				&& buff->next != chan->next)
604 			buff = buff->next;
605 
606 		if (!buff)
607 			BUG();
608 
609 		if (buff == chan->next)
610 			buff = chan->end;
611 
612 		s3c64xx_dma_bufffdone(chan, buff, res);
613 
614 		/* Free the node and update curr, if non-circular queue */
615 		if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
616 			chan->curr = buff->next;
617 			s3c64xx_dma_freebuff(buff);
618 		}
619 
620 		/* Update 'next' */
621 		buff = chan->next;
622 		if (chan->next == chan->end) {
623 			chan->next = chan->curr;
624 			if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
625 				chan->end = NULL;
626 		} else {
627 			chan->next = buff->next;
628 		}
629 	}
630 
631 	return IRQ_HANDLED;
632 }
633 
634 static struct sysdev_class dma_sysclass = {
635 	.name		= "s3c64xx-dma",
636 };
637 
s3c64xx_dma_init1(int chno,enum dma_ch chbase,int irq,unsigned int base)638 static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
639 			     int irq, unsigned int base)
640 {
641 	struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
642 	struct s3c64xx_dmac *dmac;
643 	char clkname[16];
644 	void __iomem *regs;
645 	void __iomem *regptr;
646 	int err, ch;
647 
648 	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
649 	if (!dmac) {
650 		printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
651 		return -ENOMEM;
652 	}
653 
654 	dmac->sysdev.id = chno / 8;
655 	dmac->sysdev.cls = &dma_sysclass;
656 
657 	err = sysdev_register(&dmac->sysdev);
658 	if (err) {
659 		printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
660 		goto err_alloc;
661 	}
662 
663 	regs = ioremap(base, 0x200);
664 	if (!regs) {
665 		printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
666 		err = -ENXIO;
667 		goto err_dev;
668 	}
669 
670 	snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
671 
672 	dmac->clk = clk_get(NULL, clkname);
673 	if (IS_ERR(dmac->clk)) {
674 		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
675 		err = PTR_ERR(dmac->clk);
676 		goto err_map;
677 	}
678 
679 	clk_enable(dmac->clk);
680 
681 	dmac->regs = regs;
682 	dmac->chanbase = chbase;
683 	dmac->channels = chptr;
684 
685 	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
686 	if (err < 0) {
687 		printk(KERN_ERR "%s: failed to get irq\n", __func__);
688 		goto err_clk;
689 	}
690 
691 	regptr = regs + PL080_Cx_BASE(0);
692 
693 	for (ch = 0; ch < 8; ch++, chptr++) {
694 		pr_debug("%s: registering DMA %d (%p)\n",
695 			 __func__, chno + ch, regptr);
696 
697 		chptr->bit = 1 << ch;
698 		chptr->number = chno + ch;
699 		chptr->dmac = dmac;
700 		chptr->regs = regptr;
701 		regptr += PL080_Cx_STRIDE;
702 	}
703 
704 	/* for the moment, permanently enable the controller */
705 	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
706 
707 	printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n",
708 	       irq, regs, chno, chno+8);
709 
710 	return 0;
711 
712 err_clk:
713 	clk_disable(dmac->clk);
714 	clk_put(dmac->clk);
715 err_map:
716 	iounmap(regs);
717 err_dev:
718 	sysdev_unregister(&dmac->sysdev);
719 err_alloc:
720 	kfree(dmac);
721 	return err;
722 }
723 
s3c64xx_dma_init(void)724 static int __init s3c64xx_dma_init(void)
725 {
726 	int ret;
727 
728 	printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
729 
730 	dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
731 	if (!dma_pool) {
732 		printk(KERN_ERR "%s: failed to create pool\n", __func__);
733 		return -ENOMEM;
734 	}
735 
736 	ret = sysdev_class_register(&dma_sysclass);
737 	if (ret) {
738 		printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
739 		return -ENOMEM;
740 	}
741 
742 	/* Set all DMA configuration to be DMA, not SDMA */
743 	writel(0xffffff, S3C_SYSREG(0x110));
744 
745 	/* Register standard DMA controllers */
746 	s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
747 	s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
748 
749 	return 0;
750 }
751 
752 arch_initcall(s3c64xx_dma_init);
753