···112112}113113114114static void115115-dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan,115115+dmadbg_dumpregs(const char *fname, int line, s3c2410_dma_chan_t *chan,116116 struct s3c2410_dma_regstate *regs)117117{118118 printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",···132132 chan->number, fname, line, chan->load_state,133133 chan->curr, chan->next, chan->end);134134135135- dmadbg_showregs(fname, line, chan, &state);135135+ dmadbg_dumpregs(fname, line, chan, &state);136136+}137137+138138+static void139139+dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan)140140+{141141+ struct s3c2410_dma_regstate state;142142+143143+ dmadbg_capture(chan, &state);144144+ dmadbg_dumpregs(fname, line, chan, &state);136145}137146138147#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))···262253 buf->next);263254 reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;264255 } else {265265- pr_debug("load_state is %d => autoreload\n", chan->load_state);256256+ //pr_debug("load_state is %d => autoreload\n", chan->load_state);266257 reload = S3C2410_DCON_AUTORELOAD;258258+ }259259+260260+ if ((buf->data & 0xf0000000) != 0x30000000) {261261+ dmawarn("dmaload: buffer is %p\n", (void *)buf->data);267262 }268263269264 writel(buf->data, chan->addr_reg);···383370 tmp |= S3C2410_DMASKTRIG_ON;384371 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);385372386386- pr_debug("wrote %08lx to DMASKTRIG\n", tmp);373373+ pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);387374388375#if 0389376 /* the dma buffer loads should take care of clearing the AUTO···397384398385 dbg_showchan(chan);399386387387+ /* if we've only loaded one buffer onto the channel, then chec388388+ * to see if we have another, and if so, try and load it so when389389+ * the first buffer is finished, the new one will be loaded onto390390+ * the channel */391391+392392+ if (chan->next != NULL) {393393+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {394394+395395+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {396396+ pr_debug("%s: buff not yet loaded, no more todo\n",397397+ __FUNCTION__);398398+ } else {399399+ chan->load_state = S3C2410_DMALOAD_1RUNNING;400400+ s3c2410_dma_loadbuffer(chan, chan->next);401401+ }402402+403403+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {404404+ s3c2410_dma_loadbuffer(chan, chan->next);405405+ }406406+ }407407+408408+400409 local_irq_restore(flags);410410+401411 return 0;402412}403413···472436 buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);473437 if (buf == NULL) {474438 pr_debug("%s: out of memory (%ld alloc)\n",475475- __FUNCTION__, sizeof(*buf));439439+ __FUNCTION__, (long)sizeof(*buf));476440 return -ENOMEM;477441 }478442479479- pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);480480-443443+ //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);481444 //dbg_showchan(chan);482445483446 buf->next = NULL;···572537 case S3C2410_DMALOAD_1LOADED:573538 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {574539 /* flag error? */575575- printk(KERN_ERR "dma%d: timeout waiting for load\n",576576- chan->number);540540+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",541541+ chan->number, __FUNCTION__);577542 return;578543 }579544 break;580545546546+ case S3C2410_DMALOAD_1LOADED_1RUNNING:547547+ /* I belive in this case we do not have anything to do548548+ * until the next buffer comes along, and we turn off the549549+ * reload */550550+ return;551551+581552 default:582582- pr_debug("dma%d: lastxfer: unhandled load_state %d with no next",553553+ pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",583554 chan->number, chan->load_state);584555 return;585556···670629 } else {671630 }672631673673- if (chan->next != NULL) {632632+ /* only reload if the channel is still running... our buffer done633633+ * routine may have altered the state by requesting the dma channel634634+ * to stop or shutdown... */635635+636636+ /* todo: check that when the channel is shut-down from inside this637637+ * function, we cope with unsetting reload, etc */638638+639639+ if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {674640 unsigned long flags;675641676642 switch (chan->load_state) {···692644 case S3C2410_DMALOAD_1LOADED:693645 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {694646 /* flag error? */695695- printk(KERN_ERR "dma%d: timeout waiting for load\n",696696- chan->number);647647+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",648648+ chan->number, __FUNCTION__);697649 return IRQ_HANDLED;698650 }699651···725677 no_load:726678 return IRQ_HANDLED;727679}728728-729729-730680731681/* s3c2410_request_dma732682 *···764718 pr_debug("dma%d: %s : requesting irq %d\n",765719 channel, __FUNCTION__, chan->irq);766720721721+ chan->irq_claimed = 1;722722+ local_irq_restore(flags);723723+767724 err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,768725 client->name, (void *)chan);769726727727+ local_irq_save(flags);728728+770729 if (err) {771730 chan->in_use = 0;731731+ chan->irq_claimed = 0;772732 local_irq_restore(flags);773733774734 printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",···782730 return err;783731 }784732785785- chan->irq_claimed = 1;786733 chan->irq_enabled = 1;787734 }788735···861810862811 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);863812 tmp |= S3C2410_DMASKTRIG_STOP;813813+ //tmp &= ~S3C2410_DMASKTRIG_ON;864814 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);865815866816#if 0···871819 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);872820#endif873821822822+ /* should stop do this, or should we wait for flush? */874823 chan->state = S3C2410_DMA_IDLE;875824 chan->load_state = S3C2410_DMALOAD_NONE;876825···879826880827 return 0;881828}829829+830830+void s3c2410_dma_waitforstop(s3c2410_dma_chan_t *chan)831831+{832832+ unsigned long tmp;833833+ unsigned int timeout = 0x10000;834834+835835+ while (timeout-- > 0) {836836+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);837837+838838+ if (!(tmp & S3C2410_DMASKTRIG_ON))839839+ return;840840+ }841841+842842+ pr_debug("dma%d: failed to stop?\n", chan->number);843843+}844844+882845883846/* s3c2410_dma_flush884847 *···906837 s3c2410_dma_buf_t *buf, *next;907838 unsigned long flags;908839909909- pr_debug("%s:\n", __FUNCTION__);840840+ pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);841841+842842+ dbg_showchan(chan);910843911844 local_irq_save(flags);912845···935864 }936865 }937866867867+ dbg_showregs(chan);868868+869869+ s3c2410_dma_waitforstop(chan);870870+871871+#if 0872872+ /* should also clear interrupts, according to WinCE BSP */873873+ {874874+ unsigned long tmp;875875+876876+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);877877+ tmp |= S3C2410_DCON_NORELOAD;878878+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);879879+ }880880+#endif881881+882882+ dbg_showregs(chan);883883+938884 local_irq_restore(flags);939885940886 return 0;941887}942888889889+int890890+s3c2410_dma_started(s3c2410_dma_chan_t *chan)891891+{892892+ unsigned long flags;893893+894894+ local_irq_save(flags);895895+896896+ dbg_showchan(chan);897897+898898+ /* if we've only loaded one buffer onto the channel, then chec899899+ * to see if we have another, and if so, try and load it so when900900+ * the first buffer is finished, the new one will be loaded onto901901+ * the channel */902902+903903+ if (chan->next != NULL) {904904+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {905905+906906+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {907907+ pr_debug("%s: buff not yet loaded, no more todo\n",908908+ __FUNCTION__);909909+ } else {910910+ chan->load_state = S3C2410_DMALOAD_1RUNNING;911911+ s3c2410_dma_loadbuffer(chan, chan->next);912912+ }913913+914914+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {915915+ s3c2410_dma_loadbuffer(chan, chan->next);916916+ }917917+ }918918+919919+920920+ local_irq_restore(flags);921921+922922+ return 0;923923+924924+}943925944926int945927s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)···1009885 return s3c2410_dma_dostop(chan);10108861011887 case S3C2410_DMAOP_PAUSE:10121012- return -ENOENT;10131013-1014888 case S3C2410_DMAOP_RESUME:1015889 return -ENOENT;10168901017891 case S3C2410_DMAOP_FLUSH:1018892 return s3c2410_dma_flush(chan);893893+894894+ case S3C2410_DMAOP_STARTED:895895+ return s3c2410_dma_started(chan);10198961020897 case S3C2410_DMAOP_TIMEOUT:1021898 return 0;