Skip to content

Commit

Permalink
ALSA: timer: add config item to export PCM timer disabling for expert
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jie Yang authored and Takashi Iwai committed Oct 16, 2015
1 parent dab9981 commit 90bbaf6
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 23 deletions.
8 changes: 7 additions & 1 deletion include/sound/pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion sound/core/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion sound/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions sound/core/pcm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
36 changes: 16 additions & 20 deletions sound/core/pcm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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 = {
Expand Down

0 comments on commit 90bbaf6

Please sign in to comment.