summaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/amdtp.c8
-rw-r--r--sound/firewire/amdtp.h1
2 files changed, 8 insertions, 1 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index c2685fbd7366..ea995af6d049 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -178,6 +178,7 @@ void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s)
tasklet_kill(&s->period_tasklet);
s->pcm_buffer_pointer = 0;
s->pcm_period_pointer = 0;
+ s->pointer_flush = true;
}
EXPORT_SYMBOL(amdtp_out_stream_pcm_prepare);
@@ -393,6 +394,7 @@ static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
s->pcm_period_pointer += data_blocks;
if (s->pcm_period_pointer >= pcm->runtime->period_size) {
s->pcm_period_pointer -= pcm->runtime->period_size;
+ s->pointer_flush = false;
tasklet_hi_schedule(&s->period_tasklet);
}
}
@@ -539,7 +541,11 @@ EXPORT_SYMBOL(amdtp_out_stream_start);
*/
unsigned long amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s)
{
- fw_iso_context_flush_completions(s->context);
+ /* this optimization is allowed to be racy */
+ if (s->pointer_flush)
+ fw_iso_context_flush_completions(s->context);
+ else
+ s->pointer_flush = true;
return ACCESS_ONCE(s->pcm_buffer_pointer);
}
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h
index 3f13ff63c5d2..b680c5ef01d6 100644
--- a/sound/firewire/amdtp.h
+++ b/sound/firewire/amdtp.h
@@ -68,6 +68,7 @@ struct amdtp_out_stream {
unsigned int pcm_buffer_pointer;
unsigned int pcm_period_pointer;
+ bool pointer_flush;
};
int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,