]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - sound/core/pcm_native.c
Merge branches 'x86/urgent', 'x86/amd-iommu', 'x86/apic', 'x86/cleanups', 'x86/core...
[karo-tx-linux.git] / sound / core / pcm_native.c
index 3fc33deabe356912e5b192909d0c0c3a7a46567e..c49b9d9e303c76d6495943b5b99fb02eff710e1f 100644 (file)
  *
  */
 
-#include <sound/driver.h>
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/time.h>
-#include <linux/latency.h>
+#include <linux/pm_qos_params.h>
 #include <linux/uio.h>
 #include <sound/core.h>
 #include <sound/control.h>
@@ -413,7 +413,6 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
        runtime->period_size = params_period_size(params);
        runtime->periods = params_periods(params);
        runtime->buffer_size = params_buffer_size(params);
-       runtime->tick_time = params_tick_time(params);
        runtime->info = params->info;
        runtime->rate_num = params->rate_num;
        runtime->rate_den = params->rate_den;
@@ -433,9 +432,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
        /* Default sw params */
        runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
        runtime->period_step = 1;
-       runtime->sleep_min = 0;
        runtime->control->avail_min = runtime->period_size;
-       runtime->xfer_align = runtime->period_size;
        runtime->start_threshold = 1;
        runtime->stop_threshold = runtime->buffer_size;
        runtime->silence_threshold = 0;
@@ -447,9 +444,11 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
        snd_pcm_timer_resolution_change(substream);
        runtime->status->state = SNDRV_PCM_STATE_SETUP;
 
-       remove_acceptable_latency(substream->latency_id);
+       pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
+                               substream->latency_id);
        if ((usecs = period_to_usecs(runtime)) >= 0)
-               set_acceptable_latency(substream->latency_id, usecs);
+               pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
+                                       substream->latency_id, usecs);
        return 0;
  _error:
        /* hardware might be unuseable from this time,
@@ -509,7 +508,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
        if (substream->ops->hw_free)
                result = substream->ops->hw_free(substream);
        runtime->status->state = SNDRV_PCM_STATE_OPEN;
-       remove_acceptable_latency(substream->latency_id);
+       pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
+               substream->latency_id);
        return result;
 }
 
@@ -532,9 +532,6 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        if (params->avail_min == 0)
                return -EINVAL;
-       if (params->xfer_align == 0 ||
-           params->xfer_align % runtime->min_align != 0)
-               return -EINVAL;
        if (params->silence_size >= runtime->boundary) {
                if (params->silence_threshold != 0)
                        return -EINVAL;
@@ -546,20 +543,14 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
        }
        snd_pcm_stream_lock_irq(substream);
        runtime->tstamp_mode = params->tstamp_mode;
-       runtime->sleep_min = params->sleep_min;
        runtime->period_step = params->period_step;
        runtime->control->avail_min = params->avail_min;
        runtime->start_threshold = params->start_threshold;
        runtime->stop_threshold = params->stop_threshold;
        runtime->silence_threshold = params->silence_threshold;
        runtime->silence_size = params->silence_size;
-       runtime->xfer_align = params->xfer_align;
         params->boundary = runtime->boundary;
        if (snd_pcm_running(substream)) {
-               if (runtime->sleep_min)
-                       snd_pcm_tick_prepare(substream);
-               else
-                       snd_pcm_tick_set(substream, 0);
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
                    runtime->silence_size > 0)
                        snd_pcm_playback_silence(substream, ULONG_MAX);
@@ -593,9 +584,15 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
        if (status->state == SNDRV_PCM_STATE_OPEN)
                goto _end;
        status->trigger_tstamp = runtime->trigger_tstamp;
-       if (snd_pcm_running(substream))
+       if (snd_pcm_running(substream)) {
                snd_pcm_update_hw_ptr(substream);
+               if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
+                       status->tstamp = runtime->status->tstamp;
+                       goto _tstamp_end;
+               }
+       }
        snd_pcm_gettime(runtime, &status->tstamp);
+ _tstamp_end:
        status->appl_ptr = runtime->control->appl_ptr;
        status->hw_ptr = runtime->status->hw_ptr;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -870,8 +867,6 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
            runtime->silence_size > 0)
                snd_pcm_playback_silence(substream, ULONG_MAX);
-       if (runtime->sleep_min)
-               snd_pcm_tick_prepare(substream);
        if (substream->timer)
                snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
                                 &runtime->trigger_tstamp);
@@ -925,7 +920,6 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
                        snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
                                         &runtime->trigger_tstamp);
                runtime->status->state = state;
-               snd_pcm_tick_set(substream, 0);
        }
        wake_up(&runtime->sleep);
 }
@@ -1009,12 +1003,9 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
                        snd_timer_notify(substream->timer,
                                         SNDRV_TIMER_EVENT_MPAUSE,
                                         &runtime->trigger_tstamp);
-               snd_pcm_tick_set(substream, 0);
                wake_up(&runtime->sleep);
        } else {
                runtime->status->state = SNDRV_PCM_STATE_RUNNING;
-               if (runtime->sleep_min)
-                       snd_pcm_tick_prepare(substream);
                if (substream->timer)
                        snd_timer_notify(substream->timer,
                                         SNDRV_TIMER_EVENT_MCONTINUE,
@@ -1069,7 +1060,6 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
                                 &runtime->trigger_tstamp);
        runtime->status->suspended_state = runtime->status->state;
        runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
-       snd_pcm_tick_set(substream, 0);
        wake_up(&runtime->sleep);
 }
 
@@ -1172,8 +1162,6 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
                snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
                                 &runtime->trigger_tstamp);
        runtime->status->state = runtime->status->suspended_state;
-       if (runtime->sleep_min)
-               snd_pcm_tick_prepare(substream);
 }
 
 static struct action_ops snd_pcm_action_resume = {
@@ -2002,8 +1990,6 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
        }
 
        /* FIXME: this belong to lowlevel */
-       snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_TICK_TIME,
-                                    1000000 / HZ, 1000000 / HZ);
        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
 
        return 0;
@@ -2239,15 +2225,10 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
        }
        if (frames > (snd_pcm_uframes_t)hw_avail)
                frames = hw_avail;
-       else
-               frames -= frames % runtime->xfer_align;
        appl_ptr = runtime->control->appl_ptr - frames;
        if (appl_ptr < 0)
                appl_ptr += runtime->boundary;
        runtime->control->appl_ptr = appl_ptr;
-       if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
-           runtime->sleep_min)
-               snd_pcm_tick_prepare(substream);
        ret = frames;
  __end:
        snd_pcm_stream_unlock_irq(substream);
@@ -2289,15 +2270,10 @@ static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substr
        }
        if (frames > (snd_pcm_uframes_t)hw_avail)
                frames = hw_avail;
-       else
-               frames -= frames % runtime->xfer_align;
        appl_ptr = runtime->control->appl_ptr - frames;
        if (appl_ptr < 0)
                appl_ptr += runtime->boundary;
        runtime->control->appl_ptr = appl_ptr;
-       if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
-           runtime->sleep_min)
-               snd_pcm_tick_prepare(substream);
        ret = frames;
  __end:
        snd_pcm_stream_unlock_irq(substream);
@@ -2340,15 +2316,10 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
        }
        if (frames > (snd_pcm_uframes_t)avail)
                frames = avail;
-       else
-               frames -= frames % runtime->xfer_align;
        appl_ptr = runtime->control->appl_ptr + frames;
        if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
                appl_ptr -= runtime->boundary;
        runtime->control->appl_ptr = appl_ptr;
-       if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
-           runtime->sleep_min)
-               snd_pcm_tick_prepare(substream);
        ret = frames;
  __end:
        snd_pcm_stream_unlock_irq(substream);
@@ -2391,15 +2362,10 @@ static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *subst
        }
        if (frames > (snd_pcm_uframes_t)avail)
                frames = avail;
-       else
-               frames -= frames % runtime->xfer_align;
        appl_ptr = runtime->control->appl_ptr + frames;
        if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
                appl_ptr -= runtime->boundary;
        runtime->control->appl_ptr = appl_ptr;
-       if (runtime->status->state == SNDRV_PCM_STATE_RUNNING &&
-           runtime->sleep_min)
-               snd_pcm_tick_prepare(substream);
        ret = frames;
  __end:
        snd_pcm_stream_unlock_irq(substream);
@@ -3284,14 +3250,17 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
        struct snd_pcm_file * pcm_file;
        struct snd_pcm_substream *substream;
        struct snd_pcm_runtime *runtime;
-       int err;
+       int err = -ENXIO;
 
+       lock_kernel();
        pcm_file = file->private_data;
        substream = pcm_file->substream;
-       snd_assert(substream != NULL, return -ENXIO);
+       snd_assert(substream != NULL, goto out);
        runtime = substream->runtime;
 
        err = fasync_helper(fd, file, on, &runtime->fasync);
+out:
+       unlock_kernel();
        if (err < 0)
                return err;
        return 0;