aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2410/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-s3c2410/dma.c')
-rw-r--r--arch/arm/mach-s3c2410/dma.c243
1 files changed, 184 insertions, 59 deletions
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 094cc52745c5..cc92a7b2db88 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -60,7 +60,7 @@ static void __iomem *dma_base;
60static kmem_cache_t *dma_kmem; 60static kmem_cache_t *dma_kmem;
61 61
62/* dma channel state information */ 62/* dma channel state information */
63s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS]; 63struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
64 64
65/* debugging functions */ 65/* debugging functions */
66 66
@@ -74,7 +74,7 @@ s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS];
74#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg)) 74#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
75#else 75#else
76static inline void 76static inline void
77dma_wrreg(s3c2410_dma_chan_t *chan, int reg, unsigned long val) 77dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
78{ 78{
79 pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); 79 pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
80 writel(val, dma_regaddr(chan, reg)); 80 writel(val, dma_regaddr(chan, reg));
@@ -102,7 +102,7 @@ struct s3c2410_dma_regstate {
102*/ 102*/
103 103
104static void 104static void
105dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs) 105dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
106{ 106{
107 regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC); 107 regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
108 regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC); 108 regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
@@ -112,7 +112,7 @@ dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs)
112} 112}
113 113
114static void 114static void
115dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan, 115dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
116 struct s3c2410_dma_regstate *regs) 116 struct s3c2410_dma_regstate *regs)
117{ 117{
118 printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n", 118 printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
@@ -122,7 +122,7 @@ dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
122} 122}
123 123
124static void 124static void
125dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan) 125dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
126{ 126{
127 struct s3c2410_dma_regstate state; 127 struct s3c2410_dma_regstate state;
128 128
@@ -132,7 +132,16 @@ dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan)
132 chan->number, fname, line, chan->load_state, 132 chan->number, fname, line, chan->load_state,
133 chan->curr, chan->next, chan->end); 133 chan->curr, chan->next, chan->end);
134 134
135 dmadbg_showregs(fname, line, chan, &state); 135 dmadbg_dumpregs(fname, line, chan, &state);
136}
137
138static void
139dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
140{
141 struct s3c2410_dma_regstate state;
142
143 dmadbg_capture(chan, &state);
144 dmadbg_dumpregs(fname, line, chan, &state);
136} 145}
137 146
138#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan)) 147#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
@@ -155,7 +164,7 @@ dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan)
155*/ 164*/
156 165
157static void 166static void
158s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val) 167s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
159{ 168{
160 if (stats == NULL) 169 if (stats == NULL)
161 return; 170 return;
@@ -174,7 +183,7 @@ s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val)
174*/ 183*/
175 184
176static int 185static int
177s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line) 186s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
178{ 187{
179 int timeout = chan->load_timeout; 188 int timeout = chan->load_timeout;
180 int took; 189 int took;
@@ -221,8 +230,8 @@ s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line)
221*/ 230*/
222 231
223static inline int 232static inline int
224s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan, 233s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
225 s3c2410_dma_buf_t *buf) 234 struct s3c2410_dma_buf *buf)
226{ 235{
227 unsigned long reload; 236 unsigned long reload;
228 237
@@ -253,10 +262,14 @@ s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
253 buf->next); 262 buf->next);
254 reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0; 263 reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
255 } else { 264 } else {
256 pr_debug("load_state is %d => autoreload\n", chan->load_state); 265 //pr_debug("load_state is %d => autoreload\n", chan->load_state);
257 reload = S3C2410_DCON_AUTORELOAD; 266 reload = S3C2410_DCON_AUTORELOAD;
258 } 267 }
259 268
269 if ((buf->data & 0xf0000000) != 0x30000000) {
270 dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
271 }
272
260 writel(buf->data, chan->addr_reg); 273 writel(buf->data, chan->addr_reg);
261 274
262 dma_wrreg(chan, S3C2410_DMA_DCON, 275 dma_wrreg(chan, S3C2410_DMA_DCON,
@@ -291,7 +304,7 @@ s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
291*/ 304*/
292 305
293static void 306static void
294s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op) 307s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
295{ 308{
296 if (chan->op_fn != NULL) { 309 if (chan->op_fn != NULL) {
297 (chan->op_fn)(chan, op); 310 (chan->op_fn)(chan, op);
@@ -305,8 +318,8 @@ s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op)
305*/ 318*/
306 319
307static inline void 320static inline void
308s3c2410_dma_buffdone(s3c2410_dma_chan_t *chan, s3c2410_dma_buf_t *buf, 321s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
309 s3c2410_dma_buffresult_t result) 322 enum s3c2410_dma_buffresult result)
310{ 323{
311 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n", 324 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
312 chan->callback_fn, buf, buf->id, buf->size, result); 325 chan->callback_fn, buf, buf->id, buf->size, result);
@@ -321,7 +334,7 @@ s3c2410_dma_buffdone(s3c2410_dma_chan_t *chan, s3c2410_dma_buf_t *buf,
321 * start a dma channel going 334 * start a dma channel going
322*/ 335*/
323 336
324static int s3c2410_dma_start(s3c2410_dma_chan_t *chan) 337static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
325{ 338{
326 unsigned long tmp; 339 unsigned long tmp;
327 unsigned long flags; 340 unsigned long flags;
@@ -370,7 +383,7 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
370 tmp |= S3C2410_DMASKTRIG_ON; 383 tmp |= S3C2410_DMASKTRIG_ON;
371 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); 384 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
372 385
373 pr_debug("wrote %08lx to DMASKTRIG\n", tmp); 386 pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
374 387
375#if 0 388#if 0
376 /* the dma buffer loads should take care of clearing the AUTO 389 /* the dma buffer loads should take care of clearing the AUTO
@@ -384,7 +397,30 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
384 397
385 dbg_showchan(chan); 398 dbg_showchan(chan);
386 399
400 /* if we've only loaded one buffer onto the channel, then chec
401 * to see if we have another, and if so, try and load it so when
402 * the first buffer is finished, the new one will be loaded onto
403 * the channel */
404
405 if (chan->next != NULL) {
406 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
407
408 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
409 pr_debug("%s: buff not yet loaded, no more todo\n",
410 __FUNCTION__);
411 } else {
412 chan->load_state = S3C2410_DMALOAD_1RUNNING;
413 s3c2410_dma_loadbuffer(chan, chan->next);
414 }
415
416 } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
417 s3c2410_dma_loadbuffer(chan, chan->next);
418 }
419 }
420
421
387 local_irq_restore(flags); 422 local_irq_restore(flags);
423
388 return 0; 424 return 0;
389} 425}
390 426
@@ -394,7 +430,7 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
394*/ 430*/
395 431
396static int 432static int
397s3c2410_dma_canload(s3c2410_dma_chan_t *chan) 433s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
398{ 434{
399 if (chan->load_state == S3C2410_DMALOAD_NONE || 435 if (chan->load_state == S3C2410_DMALOAD_NONE ||
400 chan->load_state == S3C2410_DMALOAD_1RUNNING) 436 chan->load_state == S3C2410_DMALOAD_1RUNNING)
@@ -424,8 +460,8 @@ s3c2410_dma_canload(s3c2410_dma_chan_t *chan)
424int s3c2410_dma_enqueue(unsigned int channel, void *id, 460int s3c2410_dma_enqueue(unsigned int channel, void *id,
425 dma_addr_t data, int size) 461 dma_addr_t data, int size)
426{ 462{
427 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 463 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
428 s3c2410_dma_buf_t *buf; 464 struct s3c2410_dma_buf *buf;
429 unsigned long flags; 465 unsigned long flags;
430 466
431 check_channel(channel); 467 check_channel(channel);
@@ -436,12 +472,11 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
436 buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC); 472 buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
437 if (buf == NULL) { 473 if (buf == NULL) {
438 pr_debug("%s: out of memory (%ld alloc)\n", 474 pr_debug("%s: out of memory (%ld alloc)\n",
439 __FUNCTION__, sizeof(*buf)); 475 __FUNCTION__, (long)sizeof(*buf));
440 return -ENOMEM; 476 return -ENOMEM;
441 } 477 }
442 478
443 pr_debug("%s: new buffer %p\n", __FUNCTION__, buf); 479 //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
444
445 //dbg_showchan(chan); 480 //dbg_showchan(chan);
446 481
447 buf->next = NULL; 482 buf->next = NULL;
@@ -505,7 +540,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
505EXPORT_SYMBOL(s3c2410_dma_enqueue); 540EXPORT_SYMBOL(s3c2410_dma_enqueue);
506 541
507static inline void 542static inline void
508s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf) 543s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
509{ 544{
510 int magicok = (buf->magic == BUF_MAGIC); 545 int magicok = (buf->magic == BUF_MAGIC);
511 546
@@ -525,7 +560,7 @@ s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf)
525*/ 560*/
526 561
527static inline void 562static inline void
528s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan) 563s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
529{ 564{
530 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", 565 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
531 chan->number, chan->load_state); 566 chan->number, chan->load_state);
@@ -537,14 +572,20 @@ s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
537 case S3C2410_DMALOAD_1LOADED: 572 case S3C2410_DMALOAD_1LOADED:
538 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { 573 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
539 /* flag error? */ 574 /* flag error? */
540 printk(KERN_ERR "dma%d: timeout waiting for load\n", 575 printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
541 chan->number); 576 chan->number, __FUNCTION__);
542 return; 577 return;
543 } 578 }
544 break; 579 break;
545 580
581 case S3C2410_DMALOAD_1LOADED_1RUNNING:
582 /* I belive in this case we do not have anything to do
583 * until the next buffer comes along, and we turn off the
584 * reload */
585 return;
586
546 default: 587 default:
547 pr_debug("dma%d: lastxfer: unhandled load_state %d with no next", 588 pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
548 chan->number, chan->load_state); 589 chan->number, chan->load_state);
549 return; 590 return;
550 591
@@ -560,8 +601,8 @@ s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
560static irqreturn_t 601static irqreturn_t
561s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) 602s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
562{ 603{
563 s3c2410_dma_chan_t *chan = (s3c2410_dma_chan_t *)devpw; 604 struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
564 s3c2410_dma_buf_t *buf; 605 struct s3c2410_dma_buf *buf;
565 606
566 buf = chan->curr; 607 buf = chan->curr;
567 608
@@ -629,7 +670,14 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
629 } else { 670 } else {
630 } 671 }
631 672
632 if (chan->next != NULL) { 673 /* only reload if the channel is still running... our buffer done
674 * routine may have altered the state by requesting the dma channel
675 * to stop or shutdown... */
676
677 /* todo: check that when the channel is shut-down from inside this
678 * function, we cope with unsetting reload, etc */
679
680 if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
633 unsigned long flags; 681 unsigned long flags;
634 682
635 switch (chan->load_state) { 683 switch (chan->load_state) {
@@ -644,8 +692,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
644 case S3C2410_DMALOAD_1LOADED: 692 case S3C2410_DMALOAD_1LOADED:
645 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { 693 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
646 /* flag error? */ 694 /* flag error? */
647 printk(KERN_ERR "dma%d: timeout waiting for load\n", 695 printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
648 chan->number); 696 chan->number, __FUNCTION__);
649 return IRQ_HANDLED; 697 return IRQ_HANDLED;
650 } 698 }
651 699
@@ -678,17 +726,15 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
678 return IRQ_HANDLED; 726 return IRQ_HANDLED;
679} 727}
680 728
681
682
683/* s3c2410_request_dma 729/* s3c2410_request_dma
684 * 730 *
685 * get control of an dma channel 731 * get control of an dma channel
686*/ 732*/
687 733
688int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client, 734int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client,
689 void *dev) 735 void *dev)
690{ 736{
691 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 737 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
692 unsigned long flags; 738 unsigned long flags;
693 int err; 739 int err;
694 740
@@ -718,11 +764,17 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
718 pr_debug("dma%d: %s : requesting irq %d\n", 764 pr_debug("dma%d: %s : requesting irq %d\n",
719 channel, __FUNCTION__, chan->irq); 765 channel, __FUNCTION__, chan->irq);
720 766
767 chan->irq_claimed = 1;
768 local_irq_restore(flags);
769
721 err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED, 770 err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
722 client->name, (void *)chan); 771 client->name, (void *)chan);
723 772
773 local_irq_save(flags);
774
724 if (err) { 775 if (err) {
725 chan->in_use = 0; 776 chan->in_use = 0;
777 chan->irq_claimed = 0;
726 local_irq_restore(flags); 778 local_irq_restore(flags);
727 779
728 printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n", 780 printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
@@ -730,7 +782,6 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
730 return err; 782 return err;
731 } 783 }
732 784
733 chan->irq_claimed = 1;
734 chan->irq_enabled = 1; 785 chan->irq_enabled = 1;
735 } 786 }
736 787
@@ -756,9 +807,9 @@ EXPORT_SYMBOL(s3c2410_dma_request);
756 * allowed to go through. 807 * allowed to go through.
757*/ 808*/
758 809
759int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) 810int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
760{ 811{
761 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 812 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
762 unsigned long flags; 813 unsigned long flags;
763 814
764 check_channel(channel); 815 check_channel(channel);
@@ -795,7 +846,7 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
795 846
796EXPORT_SYMBOL(s3c2410_dma_free); 847EXPORT_SYMBOL(s3c2410_dma_free);
797 848
798static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan) 849static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
799{ 850{
800 unsigned long tmp; 851 unsigned long tmp;
801 unsigned long flags; 852 unsigned long flags;
@@ -810,6 +861,7 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
810 861
811 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG); 862 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
812 tmp |= S3C2410_DMASKTRIG_STOP; 863 tmp |= S3C2410_DMASKTRIG_STOP;
864 //tmp &= ~S3C2410_DMASKTRIG_ON;
813 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp); 865 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
814 866
815#if 0 867#if 0
@@ -819,6 +871,7 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
819 dma_wrreg(chan, S3C2410_DMA_DCON, tmp); 871 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
820#endif 872#endif
821 873
874 /* should stop do this, or should we wait for flush? */
822 chan->state = S3C2410_DMA_IDLE; 875 chan->state = S3C2410_DMA_IDLE;
823 chan->load_state = S3C2410_DMALOAD_NONE; 876 chan->load_state = S3C2410_DMALOAD_NONE;
824 877
@@ -827,17 +880,35 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
827 return 0; 880 return 0;
828} 881}
829 882
883void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
884{
885 unsigned long tmp;
886 unsigned int timeout = 0x10000;
887
888 while (timeout-- > 0) {
889 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
890
891 if (!(tmp & S3C2410_DMASKTRIG_ON))
892 return;
893 }
894
895 pr_debug("dma%d: failed to stop?\n", chan->number);
896}
897
898
830/* s3c2410_dma_flush 899/* s3c2410_dma_flush
831 * 900 *
832 * stop the channel, and remove all current and pending transfers 901 * stop the channel, and remove all current and pending transfers
833*/ 902*/
834 903
835static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan) 904static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
836{ 905{
837 s3c2410_dma_buf_t *buf, *next; 906 struct s3c2410_dma_buf *buf, *next;
838 unsigned long flags; 907 unsigned long flags;
839 908
840 pr_debug("%s:\n", __FUNCTION__); 909 pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
910
911 dbg_showchan(chan);
841 912
842 local_irq_save(flags); 913 local_irq_save(flags);
843 914
@@ -864,16 +935,69 @@ static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan)
864 } 935 }
865 } 936 }
866 937
938 dbg_showregs(chan);
939
940 s3c2410_dma_waitforstop(chan);
941
942#if 0
943 /* should also clear interrupts, according to WinCE BSP */
944 {
945 unsigned long tmp;
946
947 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
948 tmp |= S3C2410_DCON_NORELOAD;
949 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
950 }
951#endif
952
953 dbg_showregs(chan);
954
867 local_irq_restore(flags); 955 local_irq_restore(flags);
868 956
869 return 0; 957 return 0;
870} 958}
871 959
960int
961s3c2410_dma_started(struct s3c2410_dma_chan *chan)
962{
963 unsigned long flags;
964
965 local_irq_save(flags);
966
967 dbg_showchan(chan);
968
969 /* if we've only loaded one buffer onto the channel, then chec
970 * to see if we have another, and if so, try and load it so when
971 * the first buffer is finished, the new one will be loaded onto
972 * the channel */
973
974 if (chan->next != NULL) {
975 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
976
977 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
978 pr_debug("%s: buff not yet loaded, no more todo\n",
979 __FUNCTION__);
980 } else {
981 chan->load_state = S3C2410_DMALOAD_1RUNNING;
982 s3c2410_dma_loadbuffer(chan, chan->next);
983 }
984
985 } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
986 s3c2410_dma_loadbuffer(chan, chan->next);
987 }
988 }
989
990
991 local_irq_restore(flags);
992
993 return 0;
994
995}
872 996
873int 997int
874s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op) 998s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
875{ 999{
876 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1000 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
877 1001
878 check_channel(channel); 1002 check_channel(channel);
879 1003
@@ -885,14 +1009,15 @@ s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
885 return s3c2410_dma_dostop(chan); 1009 return s3c2410_dma_dostop(chan);
886 1010
887 case S3C2410_DMAOP_PAUSE: 1011 case S3C2410_DMAOP_PAUSE:
888 return -ENOENT;
889
890 case S3C2410_DMAOP_RESUME: 1012 case S3C2410_DMAOP_RESUME:
891 return -ENOENT; 1013 return -ENOENT;
892 1014
893 case S3C2410_DMAOP_FLUSH: 1015 case S3C2410_DMAOP_FLUSH:
894 return s3c2410_dma_flush(chan); 1016 return s3c2410_dma_flush(chan);
895 1017
1018 case S3C2410_DMAOP_STARTED:
1019 return s3c2410_dma_started(chan);
1020
896 case S3C2410_DMAOP_TIMEOUT: 1021 case S3C2410_DMAOP_TIMEOUT:
897 return 0; 1022 return 0;
898 1023
@@ -921,7 +1046,7 @@ int s3c2410_dma_config(dmach_t channel,
921 int xferunit, 1046 int xferunit,
922 int dcon) 1047 int dcon)
923{ 1048{
924 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1049 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
925 1050
926 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", 1051 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
927 __FUNCTION__, channel, xferunit, dcon); 1052 __FUNCTION__, channel, xferunit, dcon);
@@ -961,7 +1086,7 @@ EXPORT_SYMBOL(s3c2410_dma_config);
961 1086
962int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) 1087int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
963{ 1088{
964 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1089 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
965 1090
966 check_channel(channel); 1091 check_channel(channel);
967 1092
@@ -981,7 +1106,7 @@ EXPORT_SYMBOL(s3c2410_dma_setflags);
981 1106
982int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) 1107int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
983{ 1108{
984 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1109 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
985 1110
986 check_channel(channel); 1111 check_channel(channel);
987 1112
@@ -996,7 +1121,7 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn);
996 1121
997int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) 1122int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
998{ 1123{
999 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1124 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
1000 1125
1001 check_channel(channel); 1126 check_channel(channel);
1002 1127
@@ -1024,11 +1149,11 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
1024*/ 1149*/
1025 1150
1026int s3c2410_dma_devconfig(int channel, 1151int s3c2410_dma_devconfig(int channel,
1027 s3c2410_dmasrc_t source, 1152 enum s3c2410_dmasrc source,
1028 int hwcfg, 1153 int hwcfg,
1029 unsigned long devaddr) 1154 unsigned long devaddr)
1030{ 1155{
1031 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1156 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
1032 1157
1033 check_channel(channel); 1158 check_channel(channel);
1034 1159
@@ -1075,7 +1200,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
1075 1200
1076int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) 1201int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
1077{ 1202{
1078 s3c2410_dma_chan_t *chan = &s3c2410_chans[channel]; 1203 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
1079 1204
1080 check_channel(channel); 1205 check_channel(channel);
1081 1206
@@ -1097,7 +1222,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition);
1097 1222
1098static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) 1223static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
1099{ 1224{
1100 s3c2410_dma_chan_t *cp = container_of(dev, s3c2410_dma_chan_t, dev); 1225 struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
1101 1226
1102 printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); 1227 printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
1103 1228
@@ -1137,7 +1262,7 @@ static struct sysdev_class dma_sysclass = {
1137 1262
1138static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) 1263static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
1139{ 1264{
1140 memset(p, 0, sizeof(s3c2410_dma_buf_t)); 1265 memset(p, 0, sizeof(struct s3c2410_dma_buf));
1141} 1266}
1142 1267
1143 1268
@@ -1145,7 +1270,7 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
1145 1270
1146static int __init s3c2410_init_dma(void) 1271static int __init s3c2410_init_dma(void)
1147{ 1272{
1148 s3c2410_dma_chan_t *cp; 1273 struct s3c2410_dma_chan *cp;
1149 int channel; 1274 int channel;
1150 int ret; 1275 int ret;
1151 1276
@@ -1163,7 +1288,7 @@ static int __init s3c2410_init_dma(void)
1163 goto err; 1288 goto err;
1164 } 1289 }
1165 1290
1166 dma_kmem = kmem_cache_create("dma_desc", sizeof(s3c2410_dma_buf_t), 0, 1291 dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
1167 SLAB_HWCACHE_ALIGN, 1292 SLAB_HWCACHE_ALIGN,
1168 s3c2410_dma_cache_ctor, NULL); 1293 s3c2410_dma_cache_ctor, NULL);
1169 1294
@@ -1176,7 +1301,7 @@ static int __init s3c2410_init_dma(void)
1176 for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) { 1301 for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
1177 cp = &s3c2410_chans[channel]; 1302 cp = &s3c2410_chans[channel];
1178 1303
1179 memset(cp, 0, sizeof(s3c2410_dma_chan_t)); 1304 memset(cp, 0, sizeof(struct s3c2410_dma_chan));
1180 1305
1181 /* dma channel irqs are in order.. */ 1306 /* dma channel irqs are in order.. */
1182 cp->number = channel; 1307 cp->number = channel;