diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-30 03:50:58 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-30 03:50:58 +0300 |
commit | a46d3f9b1c9888a244ed1ce8da0eca98c3f378e2 (patch) | |
tree | 65eeac9c5b491e7260e4b56bcd09f1529c93cccd /sound/drivers | |
parent | 7bcd34259466413b477d85d12a48789b5e90e0f4 (diff) | |
parent | 303c146df1c4574db3495d9acc5c440dd46c6b0f (diff) | |
download | linux-a46d3f9b1c9888a244ed1ce8da0eca98c3f378e2.tar.xz |
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner:
"The timer departement presents:
- A rather large rework of the hrtimer infrastructure which
introduces softirq based hrtimers to replace the spread of
hrtimer/tasklet combos which force the actual callback execution
into softirq context. The approach is completely different from the
initial implementation which you cursed at 10 years ago rightfully.
The softirq based timers have their own queues and there is no
nasty indirection and list reshuffling in the hard interrupt
anymore. This comes with conversion of some of the hrtimer/tasklet
users, the rest and the final removal of that horrible interface
will come towards the end of the merge window or go through the
relevant maintainer trees.
Note: The top commit merged the last minute bugfix for the 10 years
old CPU hotplug bug as I wanted to make sure that I fatfinger the
merge conflict resolution myself.
- The overhaul of the STM32 clocksource/clockevents driver
- A new driver for the Spreadtrum SC9860 timer
- A new driver dor the Actions Semi S700 timer
- The usual set of fixes and updates all over the place"
* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (53 commits)
usb/gadget/NCM: Replace tasklet with softirq hrtimer
ALSA/dummy: Replace tasklet with softirq hrtimer
hrtimer: Implement SOFT/HARD clock base selection
hrtimer: Implement support for softirq based hrtimers
hrtimer: Prepare handling of hard and softirq based hrtimers
hrtimer: Add clock bases and hrtimer mode for softirq context
hrtimer: Use irqsave/irqrestore around __run_hrtimer()
hrtimer: Factor out __hrtimer_next_event_base()
hrtimer: Factor out __hrtimer_start_range_ns()
hrtimer: Remove the 'base' parameter from hrtimer_reprogram()
hrtimer: Make remote enqueue decision less restrictive
hrtimer: Unify remote enqueue handling
hrtimer: Unify hrtimer removal handling
hrtimer: Make hrtimer_force_reprogramm() unconditionally available
hrtimer: Make hrtimer_reprogramm() unconditional
hrtimer: Make hrtimer_cpu_base.next_timer handling unconditional
hrtimer: Make the remote enqueue check unconditional
hrtimer: Use accesor functions instead of direct access
hrtimer: Make the hrtimer_cpu_base::hres_active field unconditional, to simplify the code
hrtimer: Make room in 'struct hrtimer_cpu_base'
...
Diffstat (limited to 'sound/drivers')
-rw-r--r-- | sound/drivers/dummy.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 69db45bc0197..8fb9a54fe8ba 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -375,17 +375,9 @@ struct dummy_hrtimer_pcm { ktime_t period_time; atomic_t running; struct hrtimer timer; - struct tasklet_struct tasklet; struct snd_pcm_substream *substream; }; -static void dummy_hrtimer_pcm_elapsed(unsigned long priv) -{ - struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv; - if (atomic_read(&dpcm->running)) - snd_pcm_period_elapsed(dpcm->substream); -} - static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer) { struct dummy_hrtimer_pcm *dpcm; @@ -393,7 +385,14 @@ static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer) dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer); if (!atomic_read(&dpcm->running)) return HRTIMER_NORESTART; - tasklet_schedule(&dpcm->tasklet); + /* + * In cases of XRUN and draining, this calls .trigger to stop PCM + * substream. + */ + snd_pcm_period_elapsed(dpcm->substream); + if (!atomic_read(&dpcm->running)) + return HRTIMER_NORESTART; + hrtimer_forward_now(timer, dpcm->period_time); return HRTIMER_RESTART; } @@ -403,7 +402,7 @@ static int dummy_hrtimer_start(struct snd_pcm_substream *substream) struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer); - hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL); + hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL_SOFT); atomic_set(&dpcm->running, 1); return 0; } @@ -413,14 +412,14 @@ static int dummy_hrtimer_stop(struct snd_pcm_substream *substream) struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; atomic_set(&dpcm->running, 0); - hrtimer_cancel(&dpcm->timer); + if (!hrtimer_callback_running(&dpcm->timer)) + hrtimer_cancel(&dpcm->timer); return 0; } static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm) { hrtimer_cancel(&dpcm->timer); - tasklet_kill(&dpcm->tasklet); } static snd_pcm_uframes_t @@ -465,12 +464,10 @@ static int dummy_hrtimer_create(struct snd_pcm_substream *substream) if (!dpcm) return -ENOMEM; substream->runtime->private_data = dpcm; - hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); dpcm->timer.function = dummy_hrtimer_callback; dpcm->substream = substream; atomic_set(&dpcm->running, 0); - tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed, - (unsigned long)dpcm); return 0; } |