ALSA: timer: add config item to export PCM timer disabling for expert
authorJie Yang <yang.jie@intel.com>
Fri, 16 Oct 2015 09:57:46 +0000 (17:57 +0800)
committerTakashi Iwai <tiwai@suse.de>
Fri, 16 Oct 2015 12:31:38 +0000 (14:31 +0200)
PCM timer is not always used. For embedded device, we need an interface
to disable it when it is not needed, to shrink the kernel size and
memory footprint, here add CONFIG_SND_PCM_TIMER for it.

When both CONFIG_SND_PCM_TIMER and CONFIG_SND_TIMER is unselected,
about 25KB saving bonus we can get.

Please be noted that when disabled, those stubs who using pcm timer
(e.g. dmix, dsnoop & co) may work incorrectlly.

Suggested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jie Yang <yang.jie@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/pcm.h
sound/core/Kconfig
sound/core/Makefile
sound/core/pcm_lib.c
sound/core/pcm_native.c

index a4fcc9456194ff97f54888e262b34b03fb2a7c95..2882dddfc91cfb957e7b988a016e7e8086f0d674 100644 (file)
@@ -1111,10 +1111,16 @@ static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substrea
  *  Timer interface
  */
 
+#ifdef CONFIG_SND_PCM_TIMER
 void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
 void snd_pcm_timer_init(struct snd_pcm_substream *substream);
 void snd_pcm_timer_done(struct snd_pcm_substream *substream);
-
+#else
+static inline void
+snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) {}
+static inline void snd_pcm_timer_init(struct snd_pcm_substream *substream) {}
+static inline void snd_pcm_timer_done(struct snd_pcm_substream *substream) {}
+#endif
 /**
  * snd_pcm_gettime - Fill the timespec depending on the timestamp mode
  * @runtime: PCM runtime instance
index 6c96feeaf01eb08794be6321fa0ac35aba66b3e8..e3e949126a5639c6a4a623750ec35922704c5110 100644 (file)
@@ -4,7 +4,7 @@ config SND_TIMER
 
 config SND_PCM
        tristate
-       select SND_TIMER
+       select SND_TIMER if SND_PCM_TIMER
 
 config SND_PCM_ELD
        bool
@@ -93,6 +93,17 @@ config SND_PCM_OSS_PLUGINS
           support conversion of channels, formats and rates. It will
           behave like most of new OSS/Free drivers in 2.4/2.6 kernels.
 
+config SND_PCM_TIMER
+       bool "PCM timer interface" if EXPERT
+       default y
+       help
+         If you disable this option, pcm timer will be inavailable, so
+         those stubs used pcm timer (e.g. dmix, dsnoop & co) may work
+         incorrectlly.
+
+         For some embedded device, we may disable it to reduce memory
+         footprint, about 20KB on x86_64 platform.
+
 config SND_SEQUENCER_OSS
        bool "OSS Sequencer API"
        depends on SND_SEQUENCER
index 3354f91e003ad13e100887c9bf9050c5ae51252a..48ab4b8f82790809838c3a87535587636ea69ed7 100644 (file)
@@ -13,8 +13,9 @@ snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o
 snd-$(CONFIG_SND_VMASTER) += vmaster.o
 snd-$(CONFIG_SND_JACK)   += ctljack.o jack.o
 
-snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
+snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_misc.o \
                pcm_memory.o memalloc.o
+snd-pcm-$(CONFIG_SND_PCM_TIMER) += pcm_timer.o
 snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
 snd-pcm-$(CONFIG_SND_PCM_ELD) += pcm_drm_eld.o
 snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o
index 7d45645f10ba99e33b54b3218559778db3aca36a..6dc4277937b8bebb2ba092306f54b24828e1882c 100644 (file)
@@ -1883,8 +1883,10 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
            snd_pcm_update_hw_ptr0(substream, 1) < 0)
                goto _end;
 
+#ifdef CONFIG_SND_PCM_TIMER
        if (substream->timer_running)
                snd_timer_interrupt(substream->timer, 1);
+#endif
  _end:
        snd_pcm_stream_unlock_irqrestore(substream, flags);
        if (runtime->transfer_ack_end)
index 139887011ba2c4b387050e5a041878d4e4f09c84..a8b27cdc2844855fb2d030a246bf2374e7e27269 100644 (file)
@@ -486,6 +486,16 @@ static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
        snd_pcm_stream_unlock_irq(substream);
 }
 
+static inline void snd_pcm_timer_notify(struct snd_pcm_substream *substream,
+                                       int event)
+{
+#ifdef CONFIG_SND_PCM_TIMER
+       if (substream->timer)
+               snd_timer_notify(substream->timer, event,
+                                       &substream->runtime->trigger_tstamp);
+#endif
+}
+
 static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params)
 {
@@ -1043,9 +1053,7 @@ 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 (substream->timer)
-               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
-                                &runtime->trigger_tstamp);
+       snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
 }
 
 static struct action_ops snd_pcm_action_start = {
@@ -1093,9 +1101,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
        if (runtime->status->state != state) {
                snd_pcm_trigger_tstamp(substream);
                runtime->status->state = state;
-               if (substream->timer)
-                       snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
-                                        &runtime->trigger_tstamp);
+               snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTOP);
        }
        wake_up(&runtime->sleep);
        wake_up(&runtime->tsleep);
@@ -1209,18 +1215,12 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
        snd_pcm_trigger_tstamp(substream);
        if (push) {
                runtime->status->state = SNDRV_PCM_STATE_PAUSED;
-               if (substream->timer)
-                       snd_timer_notify(substream->timer,
-                                        SNDRV_TIMER_EVENT_MPAUSE,
-                                        &runtime->trigger_tstamp);
+               snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
                wake_up(&runtime->sleep);
                wake_up(&runtime->tsleep);
        } else {
                runtime->status->state = SNDRV_PCM_STATE_RUNNING;
-               if (substream->timer)
-                       snd_timer_notify(substream->timer,
-                                        SNDRV_TIMER_EVENT_MCONTINUE,
-                                        &runtime->trigger_tstamp);
+               snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MCONTINUE);
        }
 }
 
@@ -1268,9 +1268,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
        snd_pcm_trigger_tstamp(substream);
        runtime->status->suspended_state = runtime->status->state;
        runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
-       if (substream->timer)
-               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND,
-                                &runtime->trigger_tstamp);
+       snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSUSPEND);
        wake_up(&runtime->sleep);
        wake_up(&runtime->tsleep);
 }
@@ -1374,9 +1372,7 @@ static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_trigger_tstamp(substream);
        runtime->status->state = runtime->status->suspended_state;
-       if (substream->timer)
-               snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
-                                &runtime->trigger_tstamp);
+       snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MRESUME);
 }
 
 static struct action_ops snd_pcm_action_resume = {