diff options
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r-- | sound/core/timer.c | 62 |
1 files changed, 27 insertions, 35 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c index 0a984e881c10..10a79aed33f8 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -88,7 +88,7 @@ static DEFINE_MUTEX(register_mutex); | |||
88 | static int snd_timer_free(struct snd_timer *timer); | 88 | static int snd_timer_free(struct snd_timer *timer); |
89 | static int snd_timer_dev_free(struct snd_device *device); | 89 | static int snd_timer_dev_free(struct snd_device *device); |
90 | static int snd_timer_dev_register(struct snd_device *device); | 90 | static int snd_timer_dev_register(struct snd_device *device); |
91 | static int snd_timer_dev_unregister(struct snd_device *device); | 91 | static int snd_timer_dev_disconnect(struct snd_device *device); |
92 | 92 | ||
93 | static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left); | 93 | static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left); |
94 | 94 | ||
@@ -718,7 +718,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) | |||
718 | } | 718 | } |
719 | } | 719 | } |
720 | if (timer->flags & SNDRV_TIMER_FLG_RESCHED) | 720 | if (timer->flags & SNDRV_TIMER_FLG_RESCHED) |
721 | snd_timer_reschedule(timer, ticks_left); | 721 | snd_timer_reschedule(timer, timer->sticks); |
722 | if (timer->running) { | 722 | if (timer->running) { |
723 | if (timer->hw.flags & SNDRV_TIMER_HW_STOP) { | 723 | if (timer->hw.flags & SNDRV_TIMER_HW_STOP) { |
724 | timer->hw.stop(timer); | 724 | timer->hw.stop(timer); |
@@ -773,7 +773,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, | |||
773 | static struct snd_device_ops ops = { | 773 | static struct snd_device_ops ops = { |
774 | .dev_free = snd_timer_dev_free, | 774 | .dev_free = snd_timer_dev_free, |
775 | .dev_register = snd_timer_dev_register, | 775 | .dev_register = snd_timer_dev_register, |
776 | .dev_unregister = snd_timer_dev_unregister | 776 | .dev_disconnect = snd_timer_dev_disconnect, |
777 | }; | 777 | }; |
778 | 778 | ||
779 | snd_assert(tid != NULL, return -EINVAL); | 779 | snd_assert(tid != NULL, return -EINVAL); |
@@ -813,6 +813,21 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, | |||
813 | static int snd_timer_free(struct snd_timer *timer) | 813 | static int snd_timer_free(struct snd_timer *timer) |
814 | { | 814 | { |
815 | snd_assert(timer != NULL, return -ENXIO); | 815 | snd_assert(timer != NULL, return -ENXIO); |
816 | |||
817 | mutex_lock(®ister_mutex); | ||
818 | if (! list_empty(&timer->open_list_head)) { | ||
819 | struct list_head *p, *n; | ||
820 | struct snd_timer_instance *ti; | ||
821 | snd_printk(KERN_WARNING "timer %p is busy?\n", timer); | ||
822 | list_for_each_safe(p, n, &timer->open_list_head) { | ||
823 | list_del_init(p); | ||
824 | ti = list_entry(p, struct snd_timer_instance, open_list); | ||
825 | ti->timer = NULL; | ||
826 | } | ||
827 | } | ||
828 | list_del(&timer->device_list); | ||
829 | mutex_unlock(®ister_mutex); | ||
830 | |||
816 | if (timer->private_free) | 831 | if (timer->private_free) |
817 | timer->private_free(timer); | 832 | timer->private_free(timer); |
818 | kfree(timer); | 833 | kfree(timer); |
@@ -867,30 +882,13 @@ static int snd_timer_dev_register(struct snd_device *dev) | |||
867 | return 0; | 882 | return 0; |
868 | } | 883 | } |
869 | 884 | ||
870 | static int snd_timer_unregister(struct snd_timer *timer) | 885 | static int snd_timer_dev_disconnect(struct snd_device *device) |
871 | { | 886 | { |
872 | struct list_head *p, *n; | 887 | struct snd_timer *timer = device->device_data; |
873 | struct snd_timer_instance *ti; | ||
874 | |||
875 | snd_assert(timer != NULL, return -ENXIO); | ||
876 | mutex_lock(®ister_mutex); | 888 | mutex_lock(®ister_mutex); |
877 | if (! list_empty(&timer->open_list_head)) { | 889 | list_del_init(&timer->device_list); |
878 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); | ||
879 | list_for_each_safe(p, n, &timer->open_list_head) { | ||
880 | list_del_init(p); | ||
881 | ti = list_entry(p, struct snd_timer_instance, open_list); | ||
882 | ti->timer = NULL; | ||
883 | } | ||
884 | } | ||
885 | list_del(&timer->device_list); | ||
886 | mutex_unlock(®ister_mutex); | 890 | mutex_unlock(®ister_mutex); |
887 | return snd_timer_free(timer); | 891 | return 0; |
888 | } | ||
889 | |||
890 | static int snd_timer_dev_unregister(struct snd_device *device) | ||
891 | { | ||
892 | struct snd_timer *timer = device->device_data; | ||
893 | return snd_timer_unregister(timer); | ||
894 | } | 892 | } |
895 | 893 | ||
896 | void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp) | 894 | void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp) |
@@ -955,18 +953,12 @@ int snd_timer_global_register(struct snd_timer *timer) | |||
955 | return snd_timer_dev_register(&dev); | 953 | return snd_timer_dev_register(&dev); |
956 | } | 954 | } |
957 | 955 | ||
958 | int snd_timer_global_unregister(struct snd_timer *timer) | ||
959 | { | ||
960 | return snd_timer_unregister(timer); | ||
961 | } | ||
962 | |||
963 | /* | 956 | /* |
964 | * System timer | 957 | * System timer |
965 | */ | 958 | */ |
966 | 959 | ||
967 | struct snd_timer_system_private { | 960 | struct snd_timer_system_private { |
968 | struct timer_list tlist; | 961 | struct timer_list tlist; |
969 | struct timer * timer; | ||
970 | unsigned long last_expires; | 962 | unsigned long last_expires; |
971 | unsigned long last_jiffies; | 963 | unsigned long last_jiffies; |
972 | unsigned long correction; | 964 | unsigned long correction; |
@@ -978,7 +970,7 @@ static void snd_timer_s_function(unsigned long data) | |||
978 | struct snd_timer_system_private *priv = timer->private_data; | 970 | struct snd_timer_system_private *priv = timer->private_data; |
979 | unsigned long jiff = jiffies; | 971 | unsigned long jiff = jiffies; |
980 | if (time_after(jiff, priv->last_expires)) | 972 | if (time_after(jiff, priv->last_expires)) |
981 | priv->correction = (long)jiff - (long)priv->last_expires; | 973 | priv->correction += (long)jiff - (long)priv->last_expires; |
982 | snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies); | 974 | snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies); |
983 | } | 975 | } |
984 | 976 | ||
@@ -994,7 +986,7 @@ static int snd_timer_s_start(struct snd_timer * timer) | |||
994 | njiff++; | 986 | njiff++; |
995 | } else { | 987 | } else { |
996 | njiff += timer->sticks - priv->correction; | 988 | njiff += timer->sticks - priv->correction; |
997 | priv->correction -= timer->sticks; | 989 | priv->correction = 0; |
998 | } | 990 | } |
999 | priv->last_expires = priv->tlist.expires = njiff; | 991 | priv->last_expires = priv->tlist.expires = njiff; |
1000 | add_timer(&priv->tlist); | 992 | add_timer(&priv->tlist); |
@@ -1013,6 +1005,7 @@ static int snd_timer_s_stop(struct snd_timer * timer) | |||
1013 | timer->sticks = priv->last_expires - jiff; | 1005 | timer->sticks = priv->last_expires - jiff; |
1014 | else | 1006 | else |
1015 | timer->sticks = 1; | 1007 | timer->sticks = 1; |
1008 | priv->correction = 0; | ||
1016 | return 0; | 1009 | return 0; |
1017 | } | 1010 | } |
1018 | 1011 | ||
@@ -1126,7 +1119,7 @@ static void __init snd_timer_proc_init(void) | |||
1126 | 1119 | ||
1127 | static void __exit snd_timer_proc_done(void) | 1120 | static void __exit snd_timer_proc_done(void) |
1128 | { | 1121 | { |
1129 | snd_info_unregister(snd_timer_proc_entry); | 1122 | snd_info_free_entry(snd_timer_proc_entry); |
1130 | } | 1123 | } |
1131 | #else /* !CONFIG_PROC_FS */ | 1124 | #else /* !CONFIG_PROC_FS */ |
1132 | #define snd_timer_proc_init() | 1125 | #define snd_timer_proc_init() |
@@ -1982,7 +1975,7 @@ static void __exit alsa_timer_exit(void) | |||
1982 | /* unregister the system timer */ | 1975 | /* unregister the system timer */ |
1983 | list_for_each_safe(p, n, &snd_timer_list) { | 1976 | list_for_each_safe(p, n, &snd_timer_list) { |
1984 | struct snd_timer *timer = list_entry(p, struct snd_timer, device_list); | 1977 | struct snd_timer *timer = list_entry(p, struct snd_timer, device_list); |
1985 | snd_timer_unregister(timer); | 1978 | snd_timer_free(timer); |
1986 | } | 1979 | } |
1987 | snd_timer_proc_done(); | 1980 | snd_timer_proc_done(); |
1988 | #ifdef SNDRV_OSS_INFO_DEV_TIMERS | 1981 | #ifdef SNDRV_OSS_INFO_DEV_TIMERS |
@@ -2005,5 +1998,4 @@ EXPORT_SYMBOL(snd_timer_notify); | |||
2005 | EXPORT_SYMBOL(snd_timer_global_new); | 1998 | EXPORT_SYMBOL(snd_timer_global_new); |
2006 | EXPORT_SYMBOL(snd_timer_global_free); | 1999 | EXPORT_SYMBOL(snd_timer_global_free); |
2007 | EXPORT_SYMBOL(snd_timer_global_register); | 2000 | EXPORT_SYMBOL(snd_timer_global_register); |
2008 | EXPORT_SYMBOL(snd_timer_global_unregister); | ||
2009 | EXPORT_SYMBOL(snd_timer_interrupt); | 2001 | EXPORT_SYMBOL(snd_timer_interrupt); |