diff options
Diffstat (limited to 'sound/core/pcm_lib.c')
-rw-r--r-- | sound/core/pcm_lib.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 11446a1506d..a82e3756a72 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -373,6 +373,27 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
373 | (unsigned long)new_hw_ptr, | 373 | (unsigned long)new_hw_ptr, |
374 | (unsigned long)runtime->hw_ptr_base); | 374 | (unsigned long)runtime->hw_ptr_base); |
375 | } | 375 | } |
376 | |||
377 | if (runtime->no_period_wakeup) { | ||
378 | /* | ||
379 | * Without regular period interrupts, we have to check | ||
380 | * the elapsed time to detect xruns. | ||
381 | */ | ||
382 | jdelta = jiffies - runtime->hw_ptr_jiffies; | ||
383 | if (jdelta < runtime->hw_ptr_buffer_jiffies / 2) | ||
384 | goto no_delta_check; | ||
385 | hdelta = jdelta - delta * HZ / runtime->rate; | ||
386 | while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) { | ||
387 | delta += runtime->buffer_size; | ||
388 | hw_base += runtime->buffer_size; | ||
389 | if (hw_base >= runtime->boundary) | ||
390 | hw_base = 0; | ||
391 | new_hw_ptr = hw_base + pos; | ||
392 | hdelta -= runtime->hw_ptr_buffer_jiffies; | ||
393 | } | ||
394 | goto no_delta_check; | ||
395 | } | ||
396 | |||
376 | /* something must be really wrong */ | 397 | /* something must be really wrong */ |
377 | if (delta >= runtime->buffer_size + runtime->period_size) { | 398 | if (delta >= runtime->buffer_size + runtime->period_size) { |
378 | hw_ptr_error(substream, | 399 | hw_ptr_error(substream, |
@@ -442,6 +463,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
442 | (long)old_hw_ptr); | 463 | (long)old_hw_ptr); |
443 | } | 464 | } |
444 | 465 | ||
466 | no_delta_check: | ||
445 | if (runtime->status->hw_ptr == new_hw_ptr) | 467 | if (runtime->status->hw_ptr == new_hw_ptr) |
446 | return 0; | 468 | return 0; |
447 | 469 | ||