summaryrefslogtreecommitdiff
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/pcm_lib.c22
-rw-r--r--sound/core/pcm_native.c3
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/sound.c18
-rw-r--r--sound/core/timer.c7
5 files changed, 47 insertions, 7 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b75db8e9cc0f..fd18c3c6484f 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,
(unsigned long)new_hw_ptr,
(unsigned long)runtime->hw_ptr_base);
}
+
+ if (runtime->no_period_wakeup) {
+ /*
+ * Without regular period interrupts, we have to check
+ * the elapsed time to detect xruns.
+ */
+ jdelta = jiffies - runtime->hw_ptr_jiffies;
+ if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
+ goto no_delta_check;
+ hdelta = jdelta - delta * HZ / runtime->rate;
+ while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) {
+ delta += runtime->buffer_size;
+ hw_base += runtime->buffer_size;
+ if (hw_base >= runtime->boundary)
+ hw_base = 0;
+ new_hw_ptr = hw_base + pos;
+ hdelta -= runtime->hw_ptr_buffer_jiffies;
+ }
+ goto no_delta_check;
+ }
+
/* something must be really wrong */
if (delta >= runtime->buffer_size + runtime->period_size) {
hw_ptr_error(substream,
@@ -442,6 +463,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
(long)old_hw_ptr);
}
+ no_delta_check:
if (runtime->status->hw_ptr == new_hw_ptr)
return 0;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e82c1f97d99e..0db714e87a80 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -422,6 +422,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
runtime->info = params->info;
runtime->rate_num = params->rate_num;
runtime->rate_den = params->rate_den;
+ runtime->no_period_wakeup =
+ (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
+ (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
bits = snd_pcm_format_physical_width(runtime->format);
runtime->sample_bits = bits;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index bf09a5ad1865..119fddb6fc99 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -32,6 +32,7 @@
#include "seq_timer.h"
#include "seq_system.h"
#include "seq_info.h"
+#include <sound/minors.h>
#include <sound/seq_device.h>
#if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
@@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe
module_param(seq_default_timer_resolution, int, 0644);
MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER);
+MODULE_ALIAS("devname:snd/seq");
+
/*
* INIT PART
*/
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 66691fe437e6..1c7a3efe1778 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -188,14 +188,22 @@ static const struct file_operations snd_fops =
};
#ifdef CONFIG_SND_DYNAMIC_MINORS
-static int snd_find_free_minor(void)
+static int snd_find_free_minor(int type)
{
int minor;
+ /* static minors for module auto loading */
+ if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
+ return SNDRV_MINOR_SEQUENCER;
+ if (type == SNDRV_DEVICE_TYPE_TIMER)
+ return SNDRV_MINOR_TIMER;
+
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
- /* skip minors still used statically for autoloading devices */
- if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL ||
- minor == SNDRV_MINOR_SEQUENCER)
+ /* skip static minors still used for module auto loading */
+ if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
+ continue;
+ if (minor == SNDRV_MINOR_SEQUENCER ||
+ minor == SNDRV_MINOR_TIMER)
continue;
if (!snd_minors[minor])
return minor;
@@ -269,7 +277,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
preg->private_data = private_data;
mutex_lock(&sound_mutex);
#ifdef CONFIG_SND_DYNAMIC_MINORS
- minor = snd_find_free_minor();
+ minor = snd_find_free_minor(type);
#else
minor = snd_kernel_minor(type, card, dev);
if (minor >= 0 && snd_minors[minor])
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 13afb60999b9..ed016329e911 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -34,8 +34,8 @@
#include <sound/initval.h>
#include <linux/kmod.h>
-#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE)
-#define DEFAULT_TIMER_LIMIT 3
+#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
+#define DEFAULT_TIMER_LIMIT 4
#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
#define DEFAULT_TIMER_LIMIT 2
#else
@@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
module_param(timer_tstamp_monotonic, int, 0444);
MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
+MODULE_ALIAS("devname:snd/timer");
+
struct snd_timer_user {
struct snd_timer_instance *timeri;
int tread; /* enhanced read with timestamps and events */