aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/timer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-06-04 05:41:48 -0400
committerTakashi Iwai <tiwai@suse.de>2018-06-04 05:42:27 -0400
commitcdbc653a04ee692a7105a96e8dd6055d9971d45c (patch)
treec1282680b3115edfd693a27bc6758208534ac557 /sound/core/timer.c
parent009f8c90f571d87855914dbc20e6c0ea2a3b19ae (diff)
parentceec4684085a9e4dc60439d84ab47ce260444804 (diff)
Merge branch 'for-next' into for-linus
4.18-rc1 merge material. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r--sound/core/timer.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 0ddcae495838..665089c45560 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -427,25 +427,35 @@ int snd_timer_close(struct snd_timer_instance *timeri)
427} 427}
428EXPORT_SYMBOL(snd_timer_close); 428EXPORT_SYMBOL(snd_timer_close);
429 429
430static unsigned long snd_timer_hw_resolution(struct snd_timer *timer)
431{
432 if (timer->hw.c_resolution)
433 return timer->hw.c_resolution(timer);
434 else
435 return timer->hw.resolution;
436}
437
430unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) 438unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
431{ 439{
432 struct snd_timer * timer; 440 struct snd_timer * timer;
441 unsigned long ret = 0;
442 unsigned long flags;
433 443
434 if (timeri == NULL) 444 if (timeri == NULL)
435 return 0; 445 return 0;
436 timer = timeri->timer; 446 timer = timeri->timer;
437 if (timer) { 447 if (timer) {
438 if (timer->hw.c_resolution) 448 spin_lock_irqsave(&timer->lock, flags);
439 return timer->hw.c_resolution(timer); 449 ret = snd_timer_hw_resolution(timer);
440 return timer->hw.resolution; 450 spin_unlock_irqrestore(&timer->lock, flags);
441 } 451 }
442 return 0; 452 return ret;
443} 453}
444EXPORT_SYMBOL(snd_timer_resolution); 454EXPORT_SYMBOL(snd_timer_resolution);
445 455
446static void snd_timer_notify1(struct snd_timer_instance *ti, int event) 456static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
447{ 457{
448 struct snd_timer *timer; 458 struct snd_timer *timer = ti->timer;
449 unsigned long resolution = 0; 459 unsigned long resolution = 0;
450 struct snd_timer_instance *ts; 460 struct snd_timer_instance *ts;
451 struct timespec tstamp; 461 struct timespec tstamp;
@@ -457,14 +467,14 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
457 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START || 467 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
458 event > SNDRV_TIMER_EVENT_PAUSE)) 468 event > SNDRV_TIMER_EVENT_PAUSE))
459 return; 469 return;
460 if (event == SNDRV_TIMER_EVENT_START || 470 if (timer &&
461 event == SNDRV_TIMER_EVENT_CONTINUE) 471 (event == SNDRV_TIMER_EVENT_START ||
462 resolution = snd_timer_resolution(ti); 472 event == SNDRV_TIMER_EVENT_CONTINUE))
473 resolution = snd_timer_hw_resolution(timer);
463 if (ti->ccallback) 474 if (ti->ccallback)
464 ti->ccallback(ti, event, &tstamp, resolution); 475 ti->ccallback(ti, event, &tstamp, resolution);
465 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) 476 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
466 return; 477 return;
467 timer = ti->timer;
468 if (timer == NULL) 478 if (timer == NULL)
469 return; 479 return;
470 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) 480 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
@@ -771,10 +781,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
771 spin_lock_irqsave(&timer->lock, flags); 781 spin_lock_irqsave(&timer->lock, flags);
772 782
773 /* remember the current resolution */ 783 /* remember the current resolution */
774 if (timer->hw.c_resolution) 784 resolution = snd_timer_hw_resolution(timer);
775 resolution = timer->hw.c_resolution(timer);
776 else
777 resolution = timer->hw.resolution;
778 785
779 /* loop for all active instances 786 /* loop for all active instances
780 * Here we cannot use list_for_each_entry because the active_list of a 787 * Here we cannot use list_for_each_entry because the active_list of a
@@ -1014,12 +1021,8 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
1014 spin_lock_irqsave(&timer->lock, flags); 1021 spin_lock_irqsave(&timer->lock, flags);
1015 if (event == SNDRV_TIMER_EVENT_MSTART || 1022 if (event == SNDRV_TIMER_EVENT_MSTART ||
1016 event == SNDRV_TIMER_EVENT_MCONTINUE || 1023 event == SNDRV_TIMER_EVENT_MCONTINUE ||
1017 event == SNDRV_TIMER_EVENT_MRESUME) { 1024 event == SNDRV_TIMER_EVENT_MRESUME)
1018 if (timer->hw.c_resolution) 1025 resolution = snd_timer_hw_resolution(timer);
1019 resolution = timer->hw.c_resolution(timer);
1020 else
1021 resolution = timer->hw.resolution;
1022 }
1023 list_for_each_entry(ti, &timer->active_list_head, active_list) { 1026 list_for_each_entry(ti, &timer->active_list_head, active_list) {
1024 if (ti->ccallback) 1027 if (ti->ccallback)
1025 ti->ccallback(ti, event, tstamp, resolution); 1028 ti->ccallback(ti, event, tstamp, resolution);
@@ -1656,10 +1659,8 @@ static int snd_timer_user_gstatus(struct file *file,
1656 mutex_lock(&register_mutex); 1659 mutex_lock(&register_mutex);
1657 t = snd_timer_find(&tid); 1660 t = snd_timer_find(&tid);
1658 if (t != NULL) { 1661 if (t != NULL) {
1659 if (t->hw.c_resolution) 1662 spin_lock_irq(&t->lock);
1660 gstatus.resolution = t->hw.c_resolution(t); 1663 gstatus.resolution = snd_timer_hw_resolution(t);
1661 else
1662 gstatus.resolution = t->hw.resolution;
1663 if (t->hw.precise_resolution) { 1664 if (t->hw.precise_resolution) {
1664 t->hw.precise_resolution(t, &gstatus.resolution_num, 1665 t->hw.precise_resolution(t, &gstatus.resolution_num,
1665 &gstatus.resolution_den); 1666 &gstatus.resolution_den);
@@ -1667,6 +1668,7 @@ static int snd_timer_user_gstatus(struct file *file,
1667 gstatus.resolution_num = gstatus.resolution; 1668 gstatus.resolution_num = gstatus.resolution;
1668 gstatus.resolution_den = 1000000000uL; 1669 gstatus.resolution_den = 1000000000uL;
1669 } 1670 }
1671 spin_unlock_irq(&t->lock);
1670 } else { 1672 } else {
1671 err = -ENODEV; 1673 err = -ENODEV;
1672 } 1674 }