Commit 60eaf398 authored by Jean-Paul Saman's avatar Jean-Paul Saman

davinci oss; rewrite to not use local_irq_{save,restore}

Use atomic types where possible and try minimizing the use of local_irq_{save,restore}.
parent 81a25387
...@@ -205,9 +205,10 @@ int audio_setup_buf(audio_stream_t * s) ...@@ -205,9 +205,10 @@ int audio_setup_buf(audio_stream_t * s)
} }
s->usr_head = s->dma_head = s->dma_tail = 0; s->usr_head = s->dma_head = s->dma_tail = 0;
AUDIO_QUEUE_INIT(s); AUDIO_QUEUE_INIT(s);
s->started = 0;
s->dma_started = 0; atomic_set(&s->started, 0);
atomic_set(&s->dma_started, 0);
s->bytecount = 0; s->bytecount = 0;
s->fragcount = 0; s->fragcount = 0;
s->prevbuf = 0; s->prevbuf = 0;
...@@ -217,6 +218,7 @@ int audio_setup_buf(audio_stream_t * s) ...@@ -217,6 +218,7 @@ int audio_setup_buf(audio_stream_t * s)
FN_OUT(0); FN_OUT(0);
return 0; return 0;
err: err:
audio_discard_buf(s); audio_discard_buf(s);
FN_OUT(1); FN_OUT(1);
...@@ -372,20 +374,16 @@ int davinci_free_sound_dma(int master_ch, int **channels) ...@@ -372,20 +374,16 @@ int davinci_free_sound_dma(int master_ch, int **channels)
int audio_process_dma(audio_stream_t * s) int audio_process_dma(audio_stream_t * s)
{ {
int ret = 0; int ret = 0;
unsigned long flags;
FN_IN; FN_IN;
/* Dont let the ISR over ride touching the in_use flag */ /* Dont let the ISR over ride touching the in_use flag */
local_irq_save(flags); if (1 == atomic_read(&s->in_use)) {
if (1 == s->in_use) {
local_irq_restore(flags);
DPRINTK("Called again while In Use\n"); DPRINTK("Called again while In Use\n");
return 0; return 0;
} }
s->in_use = 1; atomic_set(&s->in_use, 1);
local_irq_restore(flags);
if (s->stopped) if (atomic_read(&s->stopped) == 1)
goto spin; goto spin;
if (s->dma_spinref > 0 && s->pending_frags) { if (s->dma_spinref > 0 && s->pending_frags) {
...@@ -418,7 +416,7 @@ int audio_process_dma(audio_stream_t * s) ...@@ -418,7 +416,7 @@ int audio_process_dma(audio_stream_t * s)
} }
} }
spin: spin:
if (s->spin_idle) { if (atomic_read(&s->spin_idle) == 1) {
int spincnt = 0; int spincnt = 0;
DPRINTK("we are spinning\n"); DPRINTK("we are spinning\n");
while (davinci_start_sound_dma(s, SPIN_ADDR, SPIN_SIZE) == 0) while (davinci_start_sound_dma(s, SPIN_ADDR, SPIN_SIZE) == 0)
...@@ -437,7 +435,7 @@ int audio_process_dma(audio_stream_t * s) ...@@ -437,7 +435,7 @@ int audio_process_dma(audio_stream_t * s)
} }
process_out: process_out:
s->in_use = 0; atomic_set(&s->in_use, 0);
FN_OUT(ret); FN_OUT(ret);
return ret; return ret;
...@@ -452,6 +450,7 @@ int audio_process_dma(audio_stream_t * s) ...@@ -452,6 +450,7 @@ int audio_process_dma(audio_stream_t * s)
void audio_prime_rx(audio_state_t * state) void audio_prime_rx(audio_state_t * state)
{ {
audio_stream_t *is = state->input_stream; audio_stream_t *is = state->input_stream;
audio_stream_t *os = state->output_stream;
FN_IN; FN_IN;
if (state->need_tx_for_rx) { if (state->need_tx_for_rx) {
...@@ -463,15 +462,15 @@ void audio_prime_rx(audio_state_t * state) ...@@ -463,15 +462,15 @@ void audio_prime_rx(audio_state_t * state)
* will spin with all zeroes. We use the cache flush special * will spin with all zeroes. We use the cache flush special
* area for that. * area for that.
*/ */
state->output_stream->spin_idle = 1; atomic_set(&os->spin_idle, 1);
audio_process_dma(state->output_stream); audio_process_dma(os);
} }
is->pending_frags = is->nbfrags; is->pending_frags = is->nbfrags;
init_completion(&is->wfc); init_completion(&is->wfc);
is->wfc.done = 0; is->wfc.done = 0;
is->active = 1; atomic_set(&is->active, 1);
audio_process_dma(is); audio_process_dma(is);
FN_OUT(0); FN_OUT(0);
...@@ -486,7 +485,7 @@ void audio_prime_rx(audio_state_t * state) ...@@ -486,7 +485,7 @@ void audio_prime_rx(audio_state_t * state)
int audio_set_fragments(audio_stream_t * s, int val) int audio_set_fragments(audio_stream_t * s, int val)
{ {
FN_IN; FN_IN;
if (s->active) if (atomic_read(&s->active) == 1)
return -EBUSY; return -EBUSY;
if (s->buffers) if (s->buffers)
audio_discard_buf(s); audio_discard_buf(s);
...@@ -519,7 +518,6 @@ int audio_sync(struct file *file) ...@@ -519,7 +518,6 @@ int audio_sync(struct file *file)
audio_stream_t *s = state->output_stream; audio_stream_t *s = state->output_stream;
audio_buf_t *b; audio_buf_t *b;
u_int shiftval = 0; u_int shiftval = 0;
unsigned long flags;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
...@@ -548,7 +546,7 @@ int audio_sync(struct file *file) ...@@ -548,7 +546,7 @@ int audio_sync(struct file *file)
* with the start pointer here and don't forget to restore * with the start pointer here and don't forget to restore
* it later. * it later.
*/ */
local_irq_save(flags); mutex_lock(&state->mutex);
shiftval = s->fragsize - b->offset; shiftval = s->fragsize - b->offset;
if (shiftval > 0) { if (shiftval > 0) {
b->offset = shiftval; b->offset = shiftval;
...@@ -560,8 +558,8 @@ int audio_sync(struct file *file) ...@@ -560,8 +558,8 @@ int audio_sync(struct file *file)
s->usr_head = 0; s->usr_head = 0;
s->pending_frags++; s->pending_frags++;
mutex_unlock(&state->mutex);
audio_process_dma(s); audio_process_dma(s);
local_irq_restore(flags);
} }
/* Let's wait for all buffers to complete */ /* Let's wait for all buffers to complete */
...@@ -578,13 +576,13 @@ int audio_sync(struct file *file) ...@@ -578,13 +576,13 @@ int audio_sync(struct file *file)
/* undo the pointer hack above */ /* undo the pointer hack above */
if (shiftval > 0) { if (shiftval > 0) {
local_irq_save(flags); mutex_lock(&state->mutex);
b->dma_addr += shiftval; b->dma_addr += shiftval;
b->data += shiftval; b->data += shiftval;
/* ensure sane DMA code behavior if not yet processed */ /* ensure sane DMA code behavior if not yet processed */
if (b->offset != 0) if (b->offset != 0)
b->offset = s->fragsize; b->offset = s->fragsize;
local_irq_restore(flags); mutex_unlock(&state->mutex);
} }
FN_OUT(0); FN_OUT(0);
...@@ -598,20 +596,16 @@ int audio_sync(struct file *file) ...@@ -598,20 +596,16 @@ int audio_sync(struct file *file)
******************************************************************************/ ******************************************************************************/
void audio_stop_dma(audio_stream_t * s) void audio_stop_dma(audio_stream_t * s)
{ {
unsigned long flags;
FN_IN; FN_IN;
DPRINTK("audio_stop_dma\n"); DPRINTK("audio_stop_dma\n");
if (s->dma_spinref > 0 || !s->buffers) if (s->dma_spinref > 0 || !s->buffers)
return; return;
local_irq_save(flags);
davinci_stop_dma(s->master_ch); davinci_stop_dma(s->master_ch);
s->dma_started = 0; atomic_set(&s->dma_started, 0);
if (s->spin_idle) { if (atomic_read(&s->spin_idle) == 1) {
#if 0 #if 0
DMA_START(s, SPIN_ADDR, SPIN_SIZE); DMA_START(s, SPIN_ADDR, SPIN_SIZE);
DMA_START(s, SPIN_ADDR, SPIN_SIZE); DMA_START(s, SPIN_ADDR, SPIN_SIZE);
...@@ -620,8 +614,6 @@ void audio_stop_dma(audio_stream_t * s) ...@@ -620,8 +614,6 @@ void audio_stop_dma(audio_stream_t * s)
} else } else
s->dma_spinref = 0; s->dma_spinref = 0;
local_irq_restore(flags);
FN_OUT(0); FN_OUT(0);
return; return;
} }
...@@ -667,9 +659,8 @@ void audio_reset(audio_stream_t * s) ...@@ -667,9 +659,8 @@ void audio_reset(audio_stream_t * s)
audio_buf_t *b; audio_buf_t *b;
FN_IN; FN_IN;
if (s->buffers) { if (s->buffers) {
davinci_mcbsp_stop(0); davinci_mcbsp_stop(0);
s->started = 0; atomic_set(&s->started, 0);
audio_stop_dma(s); audio_stop_dma(s);
/* back up pointers to be ready to restart from the same spot */ /* back up pointers to be ready to restart from the same spot */
while (s->dma_head != s->dma_tail) { while (s->dma_head != s->dma_tail) {
...@@ -697,8 +688,10 @@ void audio_reset(audio_stream_t * s) ...@@ -697,8 +688,10 @@ void audio_reset(audio_stream_t * s)
s->wfc.done = s->nbfrags; s->wfc.done = s->nbfrags;
} }
AUDIO_QUEUE_INIT(s); AUDIO_QUEUE_INIT(s);
s->active = 0;
s->stopped = 0; atomic_set(&s->in_use, 0);
atomic_set(&s->active, 0);
atomic_set(&s->stopped, 0);
FN_OUT(0); FN_OUT(0);
return; return;
...@@ -763,18 +756,18 @@ static int audio_start_dma_chain(audio_stream_t * s) ...@@ -763,18 +756,18 @@ static int audio_start_dma_chain(audio_stream_t * s)
int channel = s->lch[s->dma_q_head]; int channel = s->lch[s->dma_q_head];
FN_IN; FN_IN;
if (!s->dma_started) { if (atomic_read(&s->dma_started) == 0) {
edmacc_paramentry_regs temp; edmacc_paramentry_regs temp;
davinci_get_dma_params(channel, &temp); davinci_get_dma_params(channel, &temp);
davinci_set_dma_params(s->master_ch, &temp); davinci_set_dma_params(s->master_ch, &temp);
davinci_start_dma(s->master_ch); davinci_start_dma(s->master_ch);
s->dma_started = 1; atomic_set(&s->dma_started, 1);
} }
if (!s->started) { if (atomic_read(&s->started) == 0) {
davinci_mcbsp_start(0); davinci_mcbsp_start(0);
s->started = 1; atomic_set(&s->started, 1);
} }
/* else the dma itself will progress forward with out our help */ /* else the dma itself will progress forward with out our help */
...@@ -978,7 +971,6 @@ static void audio_dma_callback(int lch, u16 ch_status, void *data) ...@@ -978,7 +971,6 @@ static void audio_dma_callback(int lch, u16 ch_status, void *data)
if (!s->mapped) { if (!s->mapped) {
complete(&s->wfc); complete(&s->wfc);
s->done_flag = 1;
} else } else
s->pending_frags++; s->pending_frags++;
......
...@@ -203,19 +203,19 @@ static int audio_ldm_suspend(void *data) ...@@ -203,19 +203,19 @@ static int audio_ldm_suspend(void *data)
int stopstate; int stopstate;
if (is && is->buffers) { if (is && is->buffers) {
DPRINTK("IS Suspend\n"); DPRINTK("IS Suspend\n");
stopstate = is->stopped; stopstate = atomic_read(&is->stopped);
audio_stop_dma(is); audio_stop_dma(is);
DMA_CLEAR(is); DMA_CLEAR(is);
is->dma_spinref = 0; is->dma_spinref = 0;
is->stopped = stopstate; atomic_set(&is->stopped, stopstate);
} }
if (os && os->buffers) { if (os && os->buffers) {
DPRINTK("OS Suspend\n"); DPRINTK("OS Suspend\n");
stopstate = os->stopped; stopstate = atomic_read(&os->stopped);
audio_stop_dma(os); audio_stop_dma(os);
DMA_CLEAR(os); DMA_CLEAR(os);
os->dma_spinref = 0; os->dma_spinref = 0;
os->stopped = stopstate; atomic_set(&os->stopped, stopstate);
} }
#endif #endif
} }
...@@ -438,6 +438,10 @@ int audio_register_codec(audio_state_t * codec_state) ...@@ -438,6 +438,10 @@ int audio_register_codec(audio_state_t * codec_state)
} }
memcpy(&audio_state, codec_state, sizeof(audio_state_t)); memcpy(&audio_state, codec_state, sizeof(audio_state_t));
atomic_set(&audio_state.output_stream->in_use, 0);
atomic_set(&audio_state.input_stream->in_use, 0);
mutex_init(&audio_state.mutex); mutex_init(&audio_state.mutex);
ret = platform_device_register(&davinci_audio_device); ret = platform_device_register(&davinci_audio_device);
...@@ -508,7 +512,6 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) ...@@ -508,7 +512,6 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
audio_state_t *state = file->private_data; audio_state_t *state = file->private_data;
audio_stream_t *s = state->output_stream; audio_stream_t *s = state->output_stream;
int chunksize, ret = 0; int chunksize, ret = 0;
unsigned long flags;
DPRINTK("audio_write: count=%d\n", count); DPRINTK("audio_write: count=%d\n", count);
if (*ppos != file->f_pos) { if (*ppos != file->f_pos) {
...@@ -534,9 +537,9 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) ...@@ -534,9 +537,9 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
ret = -EAGAIN; ret = -EAGAIN;
break; break;
} else { } else {
local_irq_save(flags); mutex_lock(&state->mutex);
s->wfc.done--; s->wfc.done--;
local_irq_restore(flags); mutex_unlock(&state->mutex);
} }
} else { } else {
ret = -ERESTARTSYS; ret = -ERESTARTSYS;
...@@ -565,14 +568,14 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) ...@@ -565,14 +568,14 @@ audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
} }
/* Update pointers and send current fragment to DMA */ /* Update pointers and send current fragment to DMA */
local_irq_save(flags); mutex_lock(&state->mutex);
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 */ /* Add the num of frags pending */
s->pending_frags++; s->pending_frags++;
s->active = 1; mutex_unlock(&state->mutex);
local_irq_restore(flags); atomic_set(&s->active, 1);
audio_process_dma(s); audio_process_dma(s);
} }
...@@ -595,7 +598,6 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) ...@@ -595,7 +598,6 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
audio_state_t *state = file->private_data; audio_state_t *state = file->private_data;
audio_stream_t *s = state->input_stream; audio_stream_t *s = state->input_stream;
int chunksize, ret = 0; int chunksize, ret = 0;
unsigned long flags;
DPRINTK("audio_read: count=%d\n", count); DPRINTK("audio_read: count=%d\n", count);
...@@ -609,7 +611,7 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) ...@@ -609,7 +611,7 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
return -ENXIO; return -ENXIO;
} }
if (!s->active) { if (atomic_read(&s->active) == 0) {
if (!s->buffers && audio_setup_buf(s)) { if (!s->buffers && audio_setup_buf(s)) {
DPRINTK("AudioRead - No Memory\n"); DPRINTK("AudioRead - No Memory\n");
return -ENOMEM; return -ENOMEM;
...@@ -626,9 +628,9 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) ...@@ -626,9 +628,9 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
ret = -EAGAIN; ret = -EAGAIN;
break; break;
} else { } else {
local_irq_save(flags); mutex_lock(&state->mutex);
s->wfc.done--; s->wfc.done--;
local_irq_restore(flags); mutex_unlock(&state->mutex);
} }
} else { } else {
ret = -ERESTARTSYS; ret = -ERESTARTSYS;
...@@ -655,17 +657,16 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) ...@@ -655,17 +657,16 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
} }
/* Update pointers and return current fragment to DMA */ /* Update pointers and return current fragment to DMA */
local_irq_save(flags); mutex_lock(&state->mutex);
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++; s->pending_frags++;
local_irq_restore(flags); mutex_unlock(&state->mutex);
DPRINTK(KERN_INFO DPRINTK(KERN_INFO
"calling audio_process_dma from audio_read\n"); "calling audio_process_dma from audio_read\n");
audio_process_dma(s); audio_process_dma(s);
s->done_flag = 0;
} }
if ((buffer - buffer0)) if ((buffer - buffer0))
...@@ -748,7 +749,7 @@ audio_poll(struct file *file, struct poll_table_struct *wait) ...@@ -748,7 +749,7 @@ audio_poll(struct file *file, struct poll_table_struct *wait)
if (file->f_mode & FMODE_READ) { if (file->f_mode & FMODE_READ) {
/* Start audio input if not already active */ /* Start audio input if not already active */
if (!is->active) { if (atomic_read(&is->active) == 0) {
if (!is->buffers && audio_setup_buf(is)) if (!is->buffers && audio_setup_buf(is))
return -ENOMEM; return -ENOMEM;
audio_prime_rx(state); audio_prime_rx(state);
...@@ -872,9 +873,13 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -872,9 +873,13 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
case SNDCTL_DSP_GETTRIGGER: case SNDCTL_DSP_GETTRIGGER:
val = 0; val = 0;
if (file->f_mode & FMODE_READ && is->active && !is->stopped) if (file->f_mode & FMODE_READ &&
atomic_read(&is->active) &&
!atomic_read(&is->stopped))
val |= PCM_ENABLE_INPUT; val |= PCM_ENABLE_INPUT;
if (file->f_mode & FMODE_WRITE && os->active && !os->stopped) if (file->f_mode & FMODE_WRITE &&
atomic_read(&os->active) &&
!atomic_read(&os->stopped))
val |= PCM_ENABLE_OUTPUT; val |= PCM_ENABLE_OUTPUT;
FN_OUT(11); FN_OUT(11);
return put_user(val, (int *)arg); return put_user(val, (int *)arg);
...@@ -886,43 +891,39 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -886,43 +891,39 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
} }
if (file->f_mode & FMODE_READ) { if (file->f_mode & FMODE_READ) {
if (val & PCM_ENABLE_INPUT) { if (val & PCM_ENABLE_INPUT) {
unsigned long flags; if (atomic_read(&is->active) == 0) {
if (!is->active) {
if (!is->buffers && audio_setup_buf(is)) { if (!is->buffers && audio_setup_buf(is)) {
FN_OUT(13); FN_OUT(13);
return -ENOMEM; return -ENOMEM;
} }
audio_prime_rx(state); audio_prime_rx(state);
} }
local_irq_save(flags); atomic_set(&is->stopped, 0);
is->stopped = 0;
local_irq_restore(flags);
audio_process_dma(is); audio_process_dma(is);
} else { } else {
is->stopped = 1; atomic_set(&is->stopped, 1);
audio_stop_dma(is); audio_stop_dma(is);
} }
} }
if (file->f_mode & FMODE_WRITE) { if (file->f_mode & FMODE_WRITE) {
if (val & PCM_ENABLE_OUTPUT) { if (val & PCM_ENABLE_OUTPUT) {
unsigned long flags;
if (!os->buffers && audio_setup_buf(os)) { if (!os->buffers && audio_setup_buf(os)) {
FN_OUT(14); FN_OUT(14);
return -ENOMEM; return -ENOMEM;
} }
local_irq_save(flags);
if (os->mapped && !os->pending_frags) { if (os->mapped && !os->pending_frags) {
mutex_lock(&state->mutex);
os->pending_frags = os->nbfrags; os->pending_frags = os->nbfrags;
init_completion(&os->wfc); init_completion(&os->wfc);
os->wfc.done = 0; os->wfc.done = 0;
os->active = 1; mutex_unlock(&state->mutex);
atomic_set(&os->active, 1);
} }
os->stopped = 0; atomic_set(&os->stopped, 0);
local_irq_restore(flags);
audio_process_dma(os); audio_process_dma(os);
} else { } else {
os->stopped = 1; atomic_set(&os->stopped, 1);
audio_stop_dma(os); audio_stop_dma(os);
} }
} }
...@@ -936,25 +937,24 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -936,25 +937,24 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
audio_stream_t *s = audio_stream_t *s =
(cmd == SNDCTL_DSP_GETOPTR) ? os : is; (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
int bytecount, offset; int bytecount, offset;
unsigned long flags;
if ((s == is && !(file->f_mode & FMODE_READ)) || if ((s == is && !(file->f_mode & FMODE_READ)) ||
(s == os && !(file->f_mode & FMODE_WRITE))) { (s == os && !(file->f_mode & FMODE_WRITE))) {
FN_OUT(16); FN_OUT(16);
return -EINVAL; return -EINVAL;
} }
if (s->active) { if (atomic_read(&s->active) == 1) {
local_irq_save(flags); mutex_lock(&state->mutex);
offset = audio_get_dma_pos(s); offset = audio_get_dma_pos(s);
inf.ptr = s->dma_tail * s->fragsize + offset; inf.ptr = s->dma_tail * s->fragsize + offset;
bytecount = s->bytecount + offset; bytecount = s->bytecount + offset;
s->bytecount = -offset; s->bytecount = -offset;
inf.blocks = s->fragcount; inf.blocks = s->fragcount;
s->fragcount = 0; s->fragcount = 0;
local_irq_restore(flags);
if (bytecount < 0) if (bytecount < 0)
bytecount = 0; bytecount = 0;
inf.bytes = bytecount; inf.bytes = bytecount;
mutex_unlock(&state->mutex);
} }
FN_OUT(17); FN_OUT(17);
return copy_to_user((void *)arg, &inf, sizeof(inf)); return copy_to_user((void *)arg, &inf, sizeof(inf));
...@@ -977,6 +977,8 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -977,6 +977,8 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
FN_OUT(19); FN_OUT(19);
return -ENOMEM; return -ENOMEM;
} }
mutex_lock(&state->mutex);
b = &s->buffers[s->usr_head]; b = &s->buffers[s->usr_head];
inf.bytes = s->wfc.done * s->fragsize; inf.bytes = s->wfc.done * s->fragsize;
inf.bytes -= b->offset; inf.bytes -= b->offset;
...@@ -986,6 +988,7 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -986,6 +988,7 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
inf.fragments = inf.bytes / s->fragsize; inf.fragments = inf.bytes / s->fragsize;
inf.fragsize = s->fragsize; inf.fragsize = s->fragsize;
inf.fragstotal = s->nbfrags; inf.fragstotal = s->nbfrags;
mutex_unlock(&state->mutex);
FN_OUT(20); FN_OUT(20);
return copy_to_user((void *)arg, &inf, sizeof(inf)); return copy_to_user((void *)arg, &inf, sizeof(inf));
} }
...@@ -999,10 +1002,7 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) ...@@ -999,10 +1002,7 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
if (file->f_mode & FMODE_READ) { if (file->f_mode & FMODE_READ) {
audio_reset(is); audio_reset(is);
if (state->need_tx_for_rx) { if (state->need_tx_for_rx) {
unsigned long flags; atomic_set(&os->spin_idle, 0);
local_irq_save(flags);
os->spin_idle = 0;
local_irq_restore(flags);
} }
} }
if (file->f_mode & FMODE_WRITE) { if (file->f_mode & FMODE_WRITE) {
...@@ -1119,7 +1119,6 @@ static int audio_open(struct inode *inode, struct file *file) ...@@ -1119,7 +1119,6 @@ static int audio_open(struct inode *inode, struct file *file)
is->fragsize = AUDIO_FRAGSIZE_DEFAULT; is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
is->nbfrags = AUDIO_NBFRAGS_DEFAULT; is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
is->mapped = 0; is->mapped = 0;
is->done_flag = 0;
init_waitqueue_head(&is->wq); init_waitqueue_head(&is->wq);
} }
...@@ -1156,7 +1155,7 @@ static int audio_release(struct inode *inode, struct file *file) ...@@ -1156,7 +1155,7 @@ static int audio_release(struct inode *inode, struct file *file)
DMA_FREE(is); DMA_FREE(is);
is->dma_spinref = 0; is->dma_spinref = 0;
if (state->need_tx_for_rx) { if (state->need_tx_for_rx) {
os->spin_idle = 0; atomic_set(&os->spin_idle, 0);
if (!state->wr_ref) { if (!state->wr_ref) {
DMA_FREE(os); DMA_FREE(os);
os->dma_spinref = 0; os->dma_spinref = 0;
......
...@@ -51,11 +51,11 @@ typedef struct { ...@@ -51,11 +51,11 @@ typedef struct {
u_int pending_frags; /* Fragments sent to DMA */ u_int 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 */
char started; /* to store if the chain was started or not */ atomic_t started; /* to store if the chain was started or not */
int dma_q_head; /* DMA Channel Q Head */ int dma_q_head; /* DMA Channel Q Head */
int dma_q_tail; /* DMA Channel Q Tail */ int dma_q_tail; /* DMA Channel Q Tail */
char dma_q_count; /* DMA Channel Q Count */ char dma_q_count; /* DMA Channel Q Count */
char in_use; /* Is this is use? */ atomic_t in_use; /* Is this is use? */
int master_ch; int master_ch;
int *lch; /* Chain of channels this stream is linked to */ int *lch; /* Chain of channels this stream is linked to */
int input_or_output; /* Direction of this data stream */ int input_or_output; /* Direction of this data stream */
...@@ -65,11 +65,10 @@ typedef struct { ...@@ -65,11 +65,10 @@ typedef struct {
wait_queue_head_t wq; /* for poll */ wait_queue_head_t wq; /* for poll */
int dma_spinref; /* DMA is spinning */ int dma_spinref; /* DMA is spinning */
int mapped:1; /* mmap()'ed buffers */ int mapped:1; /* mmap()'ed buffers */
int active:1; /* actually in progress */ atomic_t active; /* actually in progress */
int stopped:1; /* might be active but stopped */ atomic_t stopped; /* might be active but stopped */
int spin_idle:1; /* have DMA spin on zeros when idle */ atomic_t spin_idle; /* have DMA spin on zeros when idle */
int dma_started; /* to store if DMA was started or not */ atomic_t dma_started; /* to store if DMA was started or not */
int done_flag;
} audio_stream_t; } audio_stream_t;
/* /*
......
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