diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 2c5f7e905ab8..51821334fcee 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -37,6 +37,7 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}"); #define MAX_PCM_SUBSTREAMS 8 +static bool use_raw_jiffies; static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; @@ -44,6 +45,8 @@ static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; static int pcm_notify[SNDRV_CARDS]; static char *timer_source[SNDRV_CARDS]; +module_param(use_raw_jiffies, bool, 0444); +MODULE_PARM_DESC(use_raw_jiffies, "Use raw jiffies follows local clocks."); module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for loopback soundcard."); module_param_array(id, charp, NULL, 0444); @@ -163,6 +166,22 @@ struct loopback_pcm { static struct platform_device *devices[SNDRV_CARDS]; +static inline unsigned long get_raw_jiffies(void) +{ + struct timespec64 ts64; + + ktime_get_raw_ts64(&ts64); + return timespec64_to_jiffies(&ts64); +} + +static inline unsigned long cycles_to_jiffies(void) +{ + if (likely(use_raw_jiffies)) + return get_raw_jiffies(); + + return jiffies; +} + static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x) { if (dpcm->pcm_rate_shift == NO_PITCH) { @@ -387,7 +406,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) err = loopback_check_format(cable, substream->stream); if (err < 0) return err; - dpcm->last_jiffies = jiffies; + dpcm->last_jiffies = cycles_to_jiffies(); dpcm->pcm_rate_shift = 0; dpcm->last_drift = 0; spin_lock(&cable->lock); @@ -419,7 +438,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: spin_lock(&cable->lock); - dpcm->last_jiffies = jiffies; + dpcm->last_jiffies = cycles_to_jiffies(); cable->pause &= ~stream; err = cable->ops->start(dpcm); spin_unlock(&cable->lock); @@ -608,15 +627,16 @@ static unsigned int loopback_jiffies_timer_pos_update cable->streams[SNDRV_PCM_STREAM_CAPTURE]; unsigned long delta_play = 0, delta_capt = 0; unsigned int running, count1, count2; + unsigned long cur_jiffies = cycles_to_jiffies(); running = cable->running ^ cable->pause; if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) { - delta_play = jiffies - dpcm_play->last_jiffies; + delta_play = cur_jiffies - dpcm_play->last_jiffies; dpcm_play->last_jiffies += delta_play; } if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) { - delta_capt = jiffies - dpcm_capt->last_jiffies; + delta_capt = cur_jiffies - dpcm_capt->last_jiffies; dpcm_capt->last_jiffies += delta_capt; } @@ -842,7 +862,7 @@ static void loopback_jiffies_timer_dpcm_info(struct loopback_pcm *dpcm, snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos); snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac); snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n", - dpcm->last_jiffies, jiffies); + dpcm->last_jiffies, cycles_to_jiffies()); snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); }