Commit a1d2027b authored by Jean-Paul Saman's avatar Jean-Paul Saman

davinci oss: make s->pending_frags an atomic_t

parent cd3a08e3
/* /*
* linux/sound/oss/davinci-audio-dma-intfc.c * linux/sound/oss/davinci-audio-dma-intfc.c
* *
...@@ -213,6 +212,8 @@ int audio_setup_buf(audio_stream_t * s) ...@@ -213,6 +212,8 @@ int audio_setup_buf(audio_stream_t * s)
s->fragcount = 0; s->fragcount = 0;
s->prevbuf = 0; s->prevbuf = 0;
if (s->wfc.done > 0)
BUG();
init_completion(&s->wfc); init_completion(&s->wfc);
s->wfc.done = s->nbfrags; s->wfc.done = s->nbfrags;
...@@ -386,12 +387,12 @@ int audio_process_dma(audio_stream_t * s) ...@@ -386,12 +387,12 @@ int audio_process_dma(audio_stream_t * s)
if (atomic_read(&s->stopped) == 1) if (atomic_read(&s->stopped) == 1)
goto spin; goto spin;
if (s->dma_spinref > 0 && s->pending_frags) { if (s->dma_spinref > 0 && atomic_read(&s->pending_frags)) {
s->dma_spinref = 0; s->dma_spinref = 0;
DMA_CLEAR(s); DMA_CLEAR(s);
} }
while (s->pending_frags) { while (atomic_read(&s->pending_frags)) {
audio_buf_t *b = &s->buffers[s->dma_head]; audio_buf_t *b = &s->buffers[s->dma_head];
u_int dma_size = s->fragsize - b->offset; u_int dma_size = s->fragsize - b->offset;
...@@ -410,7 +411,7 @@ int audio_process_dma(audio_stream_t * s) ...@@ -410,7 +411,7 @@ int audio_process_dma(audio_stream_t * s)
b->dma_ref++; b->dma_ref++;
b->offset += dma_size; b->offset += dma_size;
if (b->offset >= s->fragsize) { if (b->offset >= s->fragsize) {
s->pending_frags--; atomic_dec(&s->pending_frags);
if (++s->dma_head >= s->nbfrags) if (++s->dma_head >= s->nbfrags)
s->dma_head = 0; s->dma_head = 0;
} }
...@@ -465,7 +466,7 @@ void audio_prime_rx(audio_state_t * state) ...@@ -465,7 +466,7 @@ void audio_prime_rx(audio_state_t * state)
atomic_set(&os->spin_idle, 1); atomic_set(&os->spin_idle, 1);
audio_process_dma(os); audio_process_dma(os);
} }
is->pending_frags = is->nbfrags; atomic_set(&is->pending_frags, is->nbfrags);
init_completion(&is->wfc); init_completion(&is->wfc);
is->wfc.done = 0; is->wfc.done = 0;
...@@ -556,9 +557,9 @@ int audio_sync(struct file *file) ...@@ -556,9 +557,9 @@ int audio_sync(struct file *file)
} }
if (++s->usr_head >= s->nbfrags) if (++s->usr_head >= s->nbfrags)
s->usr_head = 0; s->usr_head = 0;
s->pending_frags++;
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
atomic_inc(&s->pending_frags);
audio_process_dma(s); audio_process_dma(s);
} }
...@@ -566,7 +567,7 @@ int audio_sync(struct file *file) ...@@ -566,7 +567,7 @@ int audio_sync(struct file *file)
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&s->wq, &wait); add_wait_queue(&s->wq, &wait);
while ((s->pending_frags || (s->wfc.done < s->nbfrags)) while ((atomic_read(&s->pending_frags) || (s->wfc.done < s->nbfrags))
&& !signal_pending(current)) { && !signal_pending(current)) {
schedule(); schedule();
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -640,7 +641,7 @@ u_int audio_get_dma_pos(audio_stream_t * s) ...@@ -640,7 +641,7 @@ u_int audio_get_dma_pos(audio_stream_t * s)
offset = temp.dst - b->dma_addr; offset = temp.dst - b->dma_addr;
if (offset >= s->fragsize) if (offset >= s->fragsize)
offset = s->fragsize - 4; offset = s->fragsize - 4;
} else if (s->pending_frags) { } else if (atomic_read(&s->pending_frags)) {
offset = b->offset; offset = b->offset;
} else { } else {
offset = 0; offset = 0;
...@@ -669,7 +670,7 @@ void audio_reset(audio_stream_t * s) ...@@ -669,7 +670,7 @@ void audio_reset(audio_stream_t * s)
b->dma_ref = 0; b->dma_ref = 0;
b->offset = 0; b->offset = 0;
} }
s->pending_frags++; atomic_inc(&s->pending_frags);
if (s->dma_head == 0) if (s->dma_head == 0)
s->dma_head = s->nbfrags; s->dma_head = s->nbfrags;
s->dma_head--; s->dma_head--;
...@@ -683,7 +684,8 @@ void audio_reset(audio_stream_t * s) ...@@ -683,7 +684,8 @@ void audio_reset(audio_stream_t * s)
s->buffers[s->dma_head].offset = 0; s->buffers[s->dma_head].offset = 0;
s->buffers[s->usr_head].offset = 0; s->buffers[s->usr_head].offset = 0;
s->usr_head = s->dma_head; s->usr_head = s->dma_head;
s->pending_frags = 0; atomic_set(&s->pending_frags, 0);
init_completion(&s->wfc); init_completion(&s->wfc);
s->wfc.done = s->nbfrags; s->wfc.done = s->nbfrags;
} }
...@@ -841,7 +843,8 @@ static void audio_dsr_handler(unsigned long inData) ...@@ -841,7 +843,8 @@ static void audio_dsr_handler(unsigned long inData)
DPRINTK("Interrupt(%d) for empty queue(h=%d, T=%d)???\n", DPRINTK("Interrupt(%d) for empty queue(h=%d, T=%d)???\n",
sound_curr_lch, s->dma_q_head, s->dma_q_tail); sound_curr_lch, s->dma_q_head, s->dma_q_tail);
DPRINTK("nbfrag=%d,pendfrags=%d,USR-H=%d, QH-%d QT-%d\n", DPRINTK("nbfrag=%d,pendfrags=%d,USR-H=%d, QH-%d QT-%d\n",
s->nbfrags, s->pending_frags, s->usr_head, s->dma_head, s->nbfrags, atomic_read(&s->pending_frags),
s->usr_head, s->dma_head,
s->dma_tail); s->dma_tail);
AUDIO_INCREMENT_HEAD(s); /* Empty the queue */ AUDIO_INCREMENT_HEAD(s); /* Empty the queue */
FN_OUT(-1); FN_OUT(-1);
...@@ -912,7 +915,7 @@ static void sound_dma_irq_handler(int sound_curr_lch, u16 ch_status, void *data) ...@@ -912,7 +915,7 @@ static void sound_dma_irq_handler(int sound_curr_lch, u16 ch_status, void *data)
if (!s->mapped) { if (!s->mapped) {
complete(&s->wfc); complete(&s->wfc);
} else } else
s->pending_frags++; atomic_inc(&s->pending_frags);
wake_up(&s->wq); wake_up(&s->wq);
} }
...@@ -972,7 +975,7 @@ static void audio_dma_callback(int lch, u16 ch_status, void *data) ...@@ -972,7 +975,7 @@ static void audio_dma_callback(int lch, u16 ch_status, void *data)
if (!s->mapped) { if (!s->mapped) {
complete(&s->wfc); complete(&s->wfc);
} else } else
s->pending_frags++; atomic_inc(&s->pending_frags);
wake_up(&s->wq); wake_up(&s->wq);
} }
......
...@@ -572,9 +572,11 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) ...@@ -572,9 +572,11 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
b->offset = 0; b->offset = 0;
if (++s->usr_head >= s->nbfrags) if (++s->usr_head >= s->nbfrags)
s->usr_head = 0; s->usr_head = 0;
/* Add the num of frags pending */
s->pending_frags++;
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
/* Add the num of frags pending */
atomic_inc(&s->pending_frags);
atomic_set(&s->active, 1); atomic_set(&s->active, 1);
audio_process_dma(s); audio_process_dma(s);
} }
...@@ -661,11 +663,13 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) ...@@ -661,11 +663,13 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
b->offset = 0; b->offset = 0;
if (++s->usr_head >= s->nbfrags) if (++s->usr_head >= s->nbfrags)
s->usr_head = 0; s->usr_head = 0;
s->pending_frags++;
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
atomic_inc(&s->pending_frags);
DPRINTK(KERN_INFO DPRINTK(KERN_INFO
"calling audio_process_dma from audio_read\n"); "calling audio_process_dma from audio_read\n");
atomic_set(&s->active, 1);
audio_process_dma(s); audio_process_dma(s);
} }
...@@ -912,9 +916,9 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -912,9 +916,9 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
FN_OUT(14); FN_OUT(14);
return -ENOMEM; return -ENOMEM;
} }
if (os->mapped && !os->pending_frags) { if (os->mapped && !atomic_read(&os->pending_frags)) {
atomic_set(&os->pending_frags, os->nbfrags);
mutex_lock(&state->mutex); mutex_lock(&state->mutex);
os->pending_frags = os->nbfrags;
init_completion(&os->wfc); init_completion(&os->wfc);
os->wfc.done = 0; os->wfc.done = 0;
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
......
...@@ -48,7 +48,7 @@ typedef struct { ...@@ -48,7 +48,7 @@ typedef struct {
u_int dma_tail; /* DMA fragment index to complete */ u_int dma_tail; /* DMA fragment index to complete */
u_int fragsize; /* fragment i.e. buffer size */ u_int fragsize; /* fragment i.e. buffer size */
u_int nbfrags; /* nbr of fragments i.e. buffers */ u_int nbfrags; /* nbr of fragments i.e. buffers */
u_int pending_frags; /* Fragments sent to DMA */ atomic_t pending_frags; /* Fragments sent to DMA */
int dma_dev; /* device identifier for DMA */ int dma_dev; /* device identifier for DMA */
u_int prevbuf; /* Prev pending frag size sent to DMA */ u_int prevbuf; /* Prev pending frag size sent to DMA */
atomic_t started; /* to store if the chain was started or not */ atomic_t started; /* to store if the chain was started or not */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment