diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-06-04 05:41:48 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-06-04 05:42:27 -0400 |
commit | cdbc653a04ee692a7105a96e8dd6055d9971d45c (patch) | |
tree | c1282680b3115edfd693a27bc6758208534ac557 /sound/core/timer.c | |
parent | 009f8c90f571d87855914dbc20e6c0ea2a3b19ae (diff) | |
parent | ceec4684085a9e4dc60439d84ab47ce260444804 (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.c | 48 |
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 | } |
428 | EXPORT_SYMBOL(snd_timer_close); | 428 | EXPORT_SYMBOL(snd_timer_close); |
429 | 429 | ||
430 | static 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 | |||
430 | unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) | 438 | unsigned 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 | } |
444 | EXPORT_SYMBOL(snd_timer_resolution); | 454 | EXPORT_SYMBOL(snd_timer_resolution); |
445 | 455 | ||
446 | static void snd_timer_notify1(struct snd_timer_instance *ti, int event) | 456 | static 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(®ister_mutex); | 1659 | mutex_lock(®ister_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 | } |