|
@@ -60,7 +60,7 @@ static void __iomem *dma_base;
|
|
|
static kmem_cache_t *dma_kmem;
|
|
|
|
|
|
/* dma channel state information */
|
|
|
-s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS];
|
|
|
+struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
|
|
|
|
|
|
/* debugging functions */
|
|
|
|
|
@@ -74,7 +74,7 @@ s3c2410_dma_chan_t s3c2410_chans[S3C2410_DMA_CHANNELS];
|
|
|
#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
|
|
|
#else
|
|
|
static inline void
|
|
|
-dma_wrreg(s3c2410_dma_chan_t *chan, int reg, unsigned long val)
|
|
|
+dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
|
|
|
{
|
|
|
pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
|
|
|
writel(val, dma_regaddr(chan, reg));
|
|
@@ -102,7 +102,7 @@ struct s3c2410_dma_regstate {
|
|
|
*/
|
|
|
|
|
|
static void
|
|
|
-dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs)
|
|
|
+dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
|
|
|
{
|
|
|
regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
|
|
|
regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
|
|
@@ -112,7 +112,7 @@ dmadbg_capture(s3c2410_dma_chan_t *chan, struct s3c2410_dma_regstate *regs)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
|
|
|
+dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
|
|
|
struct s3c2410_dma_regstate *regs)
|
|
|
{
|
|
|
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,
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan)
|
|
|
+dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
|
|
|
{
|
|
|
struct s3c2410_dma_regstate state;
|
|
|
|
|
@@ -132,7 +132,16 @@ dmadbg_showchan(const char *fname, int line, s3c2410_dma_chan_t *chan)
|
|
|
chan->number, fname, line, chan->load_state,
|
|
|
chan->curr, chan->next, chan->end);
|
|
|
|
|
|
- dmadbg_showregs(fname, line, chan, &state);
|
|
|
+ dmadbg_dumpregs(fname, line, chan, &state);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
|
|
|
+{
|
|
|
+ struct s3c2410_dma_regstate state;
|
|
|
+
|
|
|
+ dmadbg_capture(chan, &state);
|
|
|
+ dmadbg_dumpregs(fname, line, chan, &state);
|
|
|
}
|
|
|
|
|
|
#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)
|
|
|
*/
|
|
|
|
|
|
static void
|
|
|
-s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val)
|
|
|
+s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
|
|
|
{
|
|
|
if (stats == NULL)
|
|
|
return;
|
|
@@ -174,7 +183,7 @@ s3c2410_dma_stats_timeout(s3c2410_dma_stats_t *stats, int val)
|
|
|
*/
|
|
|
|
|
|
static int
|
|
|
-s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line)
|
|
|
+s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
|
|
|
{
|
|
|
int timeout = chan->load_timeout;
|
|
|
int took;
|
|
@@ -221,8 +230,8 @@ s3c2410_dma_waitforload(s3c2410_dma_chan_t *chan, int line)
|
|
|
*/
|
|
|
|
|
|
static inline int
|
|
|
-s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
|
|
|
- s3c2410_dma_buf_t *buf)
|
|
|
+s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
|
|
|
+ struct s3c2410_dma_buf *buf)
|
|
|
{
|
|
|
unsigned long reload;
|
|
|
|
|
@@ -253,10 +262,14 @@ s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
|
|
|
buf->next);
|
|
|
reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
|
|
|
} else {
|
|
|
- pr_debug("load_state is %d => autoreload\n", chan->load_state);
|
|
|
+ //pr_debug("load_state is %d => autoreload\n", chan->load_state);
|
|
|
reload = S3C2410_DCON_AUTORELOAD;
|
|
|
}
|
|
|
|
|
|
+ if ((buf->data & 0xf0000000) != 0x30000000) {
|
|
|
+ dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
|
|
|
+ }
|
|
|
+
|
|
|
writel(buf->data, chan->addr_reg);
|
|
|
|
|
|
dma_wrreg(chan, S3C2410_DMA_DCON,
|
|
@@ -291,7 +304,7 @@ s3c2410_dma_loadbuffer(s3c2410_dma_chan_t *chan,
|
|
|
*/
|
|
|
|
|
|
static void
|
|
|
-s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op)
|
|
|
+s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
|
|
|
{
|
|
|
if (chan->op_fn != NULL) {
|
|
|
(chan->op_fn)(chan, op);
|
|
@@ -305,8 +318,8 @@ s3c2410_dma_call_op(s3c2410_dma_chan_t *chan, s3c2410_chan_op_t op)
|
|
|
*/
|
|
|
|
|
|
static inline void
|
|
|
-s3c2410_dma_buffdone(s3c2410_dma_chan_t *chan, s3c2410_dma_buf_t *buf,
|
|
|
- s3c2410_dma_buffresult_t result)
|
|
|
+s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
|
|
|
+ enum s3c2410_dma_buffresult result)
|
|
|
{
|
|
|
pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
|
|
|
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,
|
|
|
* start a dma channel going
|
|
|
*/
|
|
|
|
|
|
-static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
|
|
|
+static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
|
|
|
{
|
|
|
unsigned long tmp;
|
|
|
unsigned long flags;
|
|
@@ -370,7 +383,7 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
|
|
|
tmp |= S3C2410_DMASKTRIG_ON;
|
|
|
dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
|
|
|
|
|
|
- pr_debug("wrote %08lx to DMASKTRIG\n", tmp);
|
|
|
+ pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
|
|
|
|
|
|
#if 0
|
|
|
/* 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)
|
|
|
|
|
|
dbg_showchan(chan);
|
|
|
|
|
|
+ /* if we've only loaded one buffer onto the channel, then chec
|
|
|
+ * to see if we have another, and if so, try and load it so when
|
|
|
+ * the first buffer is finished, the new one will be loaded onto
|
|
|
+ * the channel */
|
|
|
+
|
|
|
+ if (chan->next != NULL) {
|
|
|
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
|
|
|
+
|
|
|
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
|
|
|
+ pr_debug("%s: buff not yet loaded, no more todo\n",
|
|
|
+ __FUNCTION__);
|
|
|
+ } else {
|
|
|
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
|
|
|
+ s3c2410_dma_loadbuffer(chan, chan->next);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
|
|
|
+ s3c2410_dma_loadbuffer(chan, chan->next);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
local_irq_restore(flags);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -394,7 +430,7 @@ static int s3c2410_dma_start(s3c2410_dma_chan_t *chan)
|
|
|
*/
|
|
|
|
|
|
static int
|
|
|
-s3c2410_dma_canload(s3c2410_dma_chan_t *chan)
|
|
|
+s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
|
|
|
{
|
|
|
if (chan->load_state == S3C2410_DMALOAD_NONE ||
|
|
|
chan->load_state == S3C2410_DMALOAD_1RUNNING)
|
|
@@ -424,8 +460,8 @@ s3c2410_dma_canload(s3c2410_dma_chan_t *chan)
|
|
|
int s3c2410_dma_enqueue(unsigned int channel, void *id,
|
|
|
dma_addr_t data, int size)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
- s3c2410_dma_buf_t *buf;
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_buf *buf;
|
|
|
unsigned long flags;
|
|
|
|
|
|
check_channel(channel);
|
|
@@ -436,12 +472,11 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
|
|
|
buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
|
|
|
if (buf == NULL) {
|
|
|
pr_debug("%s: out of memory (%ld alloc)\n",
|
|
|
- __FUNCTION__, sizeof(*buf));
|
|
|
+ __FUNCTION__, (long)sizeof(*buf));
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
|
|
|
-
|
|
|
+ //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
|
|
|
//dbg_showchan(chan);
|
|
|
|
|
|
buf->next = NULL;
|
|
@@ -505,7 +540,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
|
|
|
EXPORT_SYMBOL(s3c2410_dma_enqueue);
|
|
|
|
|
|
static inline void
|
|
|
-s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf)
|
|
|
+s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
|
|
|
{
|
|
|
int magicok = (buf->magic == BUF_MAGIC);
|
|
|
|
|
@@ -525,7 +560,7 @@ s3c2410_dma_freebuf(s3c2410_dma_buf_t *buf)
|
|
|
*/
|
|
|
|
|
|
static inline void
|
|
|
-s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
|
|
|
+s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
|
|
|
{
|
|
|
pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
|
|
|
chan->number, chan->load_state);
|
|
@@ -537,14 +572,20 @@ s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
|
|
|
case S3C2410_DMALOAD_1LOADED:
|
|
|
if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
|
|
|
/* flag error? */
|
|
|
- printk(KERN_ERR "dma%d: timeout waiting for load\n",
|
|
|
- chan->number);
|
|
|
+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
|
|
|
+ chan->number, __FUNCTION__);
|
|
|
return;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
|
|
|
+ /* I belive in this case we do not have anything to do
|
|
|
+ * until the next buffer comes along, and we turn off the
|
|
|
+ * reload */
|
|
|
+ return;
|
|
|
+
|
|
|
default:
|
|
|
- pr_debug("dma%d: lastxfer: unhandled load_state %d with no next",
|
|
|
+ pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
|
|
|
chan->number, chan->load_state);
|
|
|
return;
|
|
|
|
|
@@ -560,8 +601,8 @@ s3c2410_dma_lastxfer(s3c2410_dma_chan_t *chan)
|
|
|
static irqreturn_t
|
|
|
s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = (s3c2410_dma_chan_t *)devpw;
|
|
|
- s3c2410_dma_buf_t *buf;
|
|
|
+ struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
|
|
|
+ struct s3c2410_dma_buf *buf;
|
|
|
|
|
|
buf = chan->curr;
|
|
|
|
|
@@ -629,7 +670,14 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
|
|
|
} else {
|
|
|
}
|
|
|
|
|
|
- if (chan->next != NULL) {
|
|
|
+ /* only reload if the channel is still running... our buffer done
|
|
|
+ * routine may have altered the state by requesting the dma channel
|
|
|
+ * to stop or shutdown... */
|
|
|
+
|
|
|
+ /* todo: check that when the channel is shut-down from inside this
|
|
|
+ * function, we cope with unsetting reload, etc */
|
|
|
+
|
|
|
+ if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
|
|
|
unsigned long flags;
|
|
|
|
|
|
switch (chan->load_state) {
|
|
@@ -644,8 +692,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
|
|
|
case S3C2410_DMALOAD_1LOADED:
|
|
|
if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
|
|
|
/* flag error? */
|
|
|
- printk(KERN_ERR "dma%d: timeout waiting for load\n",
|
|
|
- chan->number);
|
|
|
+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
|
|
|
+ chan->number, __FUNCTION__);
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
@@ -678,17 +726,15 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
/* s3c2410_request_dma
|
|
|
*
|
|
|
* get control of an dma channel
|
|
|
*/
|
|
|
|
|
|
-int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
|
|
|
+int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client,
|
|
|
void *dev)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
unsigned long flags;
|
|
|
int err;
|
|
|
|
|
@@ -718,11 +764,17 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
|
|
|
pr_debug("dma%d: %s : requesting irq %d\n",
|
|
|
channel, __FUNCTION__, chan->irq);
|
|
|
|
|
|
+ chan->irq_claimed = 1;
|
|
|
+ local_irq_restore(flags);
|
|
|
+
|
|
|
err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
|
|
|
client->name, (void *)chan);
|
|
|
|
|
|
+ local_irq_save(flags);
|
|
|
+
|
|
|
if (err) {
|
|
|
chan->in_use = 0;
|
|
|
+ chan->irq_claimed = 0;
|
|
|
local_irq_restore(flags);
|
|
|
|
|
|
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,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
- chan->irq_claimed = 1;
|
|
|
chan->irq_enabled = 1;
|
|
|
}
|
|
|
|
|
@@ -756,9 +807,9 @@ EXPORT_SYMBOL(s3c2410_dma_request);
|
|
|
* allowed to go through.
|
|
|
*/
|
|
|
|
|
|
-int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
|
|
|
+int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
unsigned long flags;
|
|
|
|
|
|
check_channel(channel);
|
|
@@ -795,7 +846,7 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client)
|
|
|
|
|
|
EXPORT_SYMBOL(s3c2410_dma_free);
|
|
|
|
|
|
-static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
|
|
|
+static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
|
|
|
{
|
|
|
unsigned long tmp;
|
|
|
unsigned long flags;
|
|
@@ -810,6 +861,7 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
|
|
|
|
|
|
tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
|
|
|
tmp |= S3C2410_DMASKTRIG_STOP;
|
|
|
+ //tmp &= ~S3C2410_DMASKTRIG_ON;
|
|
|
dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
|
|
|
|
|
|
#if 0
|
|
@@ -819,6 +871,7 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
|
|
|
dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
|
|
|
#endif
|
|
|
|
|
|
+ /* should stop do this, or should we wait for flush? */
|
|
|
chan->state = S3C2410_DMA_IDLE;
|
|
|
chan->load_state = S3C2410_DMALOAD_NONE;
|
|
|
|
|
@@ -827,17 +880,35 @@ static int s3c2410_dma_dostop(s3c2410_dma_chan_t *chan)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
|
|
|
+{
|
|
|
+ unsigned long tmp;
|
|
|
+ unsigned int timeout = 0x10000;
|
|
|
+
|
|
|
+ while (timeout-- > 0) {
|
|
|
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
|
|
|
+
|
|
|
+ if (!(tmp & S3C2410_DMASKTRIG_ON))
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_debug("dma%d: failed to stop?\n", chan->number);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/* s3c2410_dma_flush
|
|
|
*
|
|
|
* stop the channel, and remove all current and pending transfers
|
|
|
*/
|
|
|
|
|
|
-static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan)
|
|
|
+static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
|
|
|
{
|
|
|
- s3c2410_dma_buf_t *buf, *next;
|
|
|
+ struct s3c2410_dma_buf *buf, *next;
|
|
|
unsigned long flags;
|
|
|
|
|
|
- pr_debug("%s:\n", __FUNCTION__);
|
|
|
+ pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
|
|
|
+
|
|
|
+ dbg_showchan(chan);
|
|
|
|
|
|
local_irq_save(flags);
|
|
|
|
|
@@ -864,16 +935,69 @@ static int s3c2410_dma_flush(s3c2410_dma_chan_t *chan)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ dbg_showregs(chan);
|
|
|
+
|
|
|
+ s3c2410_dma_waitforstop(chan);
|
|
|
+
|
|
|
+#if 0
|
|
|
+ /* should also clear interrupts, according to WinCE BSP */
|
|
|
+ {
|
|
|
+ unsigned long tmp;
|
|
|
+
|
|
|
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
|
|
|
+ tmp |= S3C2410_DCON_NORELOAD;
|
|
|
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ dbg_showregs(chan);
|
|
|
+
|
|
|
local_irq_restore(flags);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+s3c2410_dma_started(struct s3c2410_dma_chan *chan)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ local_irq_save(flags);
|
|
|
+
|
|
|
+ dbg_showchan(chan);
|
|
|
+
|
|
|
+ /* if we've only loaded one buffer onto the channel, then chec
|
|
|
+ * to see if we have another, and if so, try and load it so when
|
|
|
+ * the first buffer is finished, the new one will be loaded onto
|
|
|
+ * the channel */
|
|
|
+
|
|
|
+ if (chan->next != NULL) {
|
|
|
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
|
|
|
+
|
|
|
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
|
|
|
+ pr_debug("%s: buff not yet loaded, no more todo\n",
|
|
|
+ __FUNCTION__);
|
|
|
+ } else {
|
|
|
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
|
|
|
+ s3c2410_dma_loadbuffer(chan, chan->next);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
|
|
|
+ s3c2410_dma_loadbuffer(chan, chan->next);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ local_irq_restore(flags);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+}
|
|
|
|
|
|
int
|
|
|
-s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
|
|
|
+s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
check_channel(channel);
|
|
|
|
|
@@ -885,14 +1009,15 @@ s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
|
|
|
return s3c2410_dma_dostop(chan);
|
|
|
|
|
|
case S3C2410_DMAOP_PAUSE:
|
|
|
- return -ENOENT;
|
|
|
-
|
|
|
case S3C2410_DMAOP_RESUME:
|
|
|
return -ENOENT;
|
|
|
|
|
|
case S3C2410_DMAOP_FLUSH:
|
|
|
return s3c2410_dma_flush(chan);
|
|
|
|
|
|
+ case S3C2410_DMAOP_STARTED:
|
|
|
+ return s3c2410_dma_started(chan);
|
|
|
+
|
|
|
case S3C2410_DMAOP_TIMEOUT:
|
|
|
return 0;
|
|
|
|
|
@@ -921,7 +1046,7 @@ int s3c2410_dma_config(dmach_t channel,
|
|
|
int xferunit,
|
|
|
int dcon)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
|
|
|
__FUNCTION__, channel, xferunit, dcon);
|
|
@@ -961,7 +1086,7 @@ EXPORT_SYMBOL(s3c2410_dma_config);
|
|
|
|
|
|
int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
check_channel(channel);
|
|
|
|
|
@@ -981,7 +1106,7 @@ EXPORT_SYMBOL(s3c2410_dma_setflags);
|
|
|
|
|
|
int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
check_channel(channel);
|
|
|
|
|
@@ -996,7 +1121,7 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn);
|
|
|
|
|
|
int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
check_channel(channel);
|
|
|
|
|
@@ -1024,11 +1149,11 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
|
|
|
*/
|
|
|
|
|
|
int s3c2410_dma_devconfig(int channel,
|
|
|
- s3c2410_dmasrc_t source,
|
|
|
+ enum s3c2410_dmasrc source,
|
|
|
int hwcfg,
|
|
|
unsigned long devaddr)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
check_channel(channel);
|
|
|
|
|
@@ -1075,7 +1200,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
|
|
|
|
|
|
int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
|
|
|
+ struct s3c2410_dma_chan *chan = &s3c2410_chans[channel];
|
|
|
|
|
|
check_channel(channel);
|
|
|
|
|
@@ -1097,7 +1222,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition);
|
|
|
|
|
|
static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *cp = container_of(dev, s3c2410_dma_chan_t, dev);
|
|
|
+ struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
|
|
|
|
|
|
printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
|
|
|
|
|
@@ -1137,7 +1262,7 @@ static struct sysdev_class dma_sysclass = {
|
|
|
|
|
|
static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
|
|
|
{
|
|
|
- memset(p, 0, sizeof(s3c2410_dma_buf_t));
|
|
|
+ memset(p, 0, sizeof(struct s3c2410_dma_buf));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1145,7 +1270,7 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
|
|
|
|
|
|
static int __init s3c2410_init_dma(void)
|
|
|
{
|
|
|
- s3c2410_dma_chan_t *cp;
|
|
|
+ struct s3c2410_dma_chan *cp;
|
|
|
int channel;
|
|
|
int ret;
|
|
|
|
|
@@ -1163,7 +1288,7 @@ static int __init s3c2410_init_dma(void)
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
- dma_kmem = kmem_cache_create("dma_desc", sizeof(s3c2410_dma_buf_t), 0,
|
|
|
+ dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
|
|
|
SLAB_HWCACHE_ALIGN,
|
|
|
s3c2410_dma_cache_ctor, NULL);
|
|
|
|
|
@@ -1176,7 +1301,7 @@ static int __init s3c2410_init_dma(void)
|
|
|
for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
|
|
|
cp = &s3c2410_chans[channel];
|
|
|
|
|
|
- memset(cp, 0, sizeof(s3c2410_dma_chan_t));
|
|
|
+ memset(cp, 0, sizeof(struct s3c2410_dma_chan));
|
|
|
|
|
|
/* dma channel irqs are in order.. */
|
|
|
cp->number = channel;
|