Lines Matching +full:timer +full:-
1 // SPDX-License-Identifier: GPL-2.0-or-later
17 #include <sound/timer.h>
37 MODULE_DESCRIPTION("ALSA timer interface");
45 MODULE_ALIAS("devname:snd/timer");
91 s32 tstamp_sec; /* Timestamp - last update */
103 s64 tstamp_sec; /* Timestamp - last update */
128 static int snd_timer_free(struct snd_timer *timer);
133 static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left);
136 * create a timer instance with the given owner string.
145 timeri->owner = kstrdup(owner, GFP_KERNEL); in snd_timer_instance_new()
146 if (! timeri->owner) { in snd_timer_instance_new()
150 INIT_LIST_HEAD(&timeri->open_list); in snd_timer_instance_new()
151 INIT_LIST_HEAD(&timeri->active_list); in snd_timer_instance_new()
152 INIT_LIST_HEAD(&timeri->ack_list); in snd_timer_instance_new()
153 INIT_LIST_HEAD(&timeri->slave_list_head); in snd_timer_instance_new()
154 INIT_LIST_HEAD(&timeri->slave_active_head); in snd_timer_instance_new()
163 if (timeri->private_free) in snd_timer_instance_free()
164 timeri->private_free(timeri); in snd_timer_instance_free()
165 kfree(timeri->owner); in snd_timer_instance_free()
172 * find a timer instance from the given timer id
176 struct snd_timer *timer; in snd_timer_find() local
178 list_for_each_entry(timer, &snd_timer_list, device_list) { in snd_timer_find()
179 if (timer->tmr_class != tid->dev_class) in snd_timer_find()
181 if ((timer->tmr_class == SNDRV_TIMER_CLASS_CARD || in snd_timer_find()
182 timer->tmr_class == SNDRV_TIMER_CLASS_PCM) && in snd_timer_find()
183 (timer->card == NULL || in snd_timer_find()
184 timer->card->number != tid->card)) in snd_timer_find()
186 if (timer->tmr_device != tid->device) in snd_timer_find()
188 if (timer->tmr_subdevice != tid->subdevice) in snd_timer_find()
190 return timer; in snd_timer_find()
199 switch (tid->dev_class) { in snd_timer_request()
201 if (tid->device < timer_limit) in snd_timer_request()
202 request_module("snd-timer-%i", tid->device); in snd_timer_request()
206 if (tid->card < snd_ecards_limit) in snd_timer_request()
207 request_module("snd-card-%i", tid->card); in snd_timer_request()
220 if (slave->slave_class != master->slave_class || in check_matching_master_slave()
221 slave->slave_id != master->slave_id) in check_matching_master_slave()
223 if (master->timer->num_instances >= master->timer->max_instances) in check_matching_master_slave()
224 return -EBUSY; in check_matching_master_slave()
225 list_move_tail(&slave->open_list, &master->slave_list_head); in check_matching_master_slave()
226 master->timer->num_instances++; in check_matching_master_slave()
228 spin_lock(&master->timer->lock); in check_matching_master_slave()
229 slave->master = master; in check_matching_master_slave()
230 slave->timer = master->timer; in check_matching_master_slave()
231 if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) in check_matching_master_slave()
232 list_add_tail(&slave->active_list, &master->slave_active_head); in check_matching_master_slave()
233 spin_unlock(&master->timer->lock); in check_matching_master_slave()
246 struct snd_timer *timer; in snd_timer_check_slave() local
251 list_for_each_entry(timer, &snd_timer_list, device_list) { in snd_timer_check_slave()
252 list_for_each_entry(master, &timer->open_list_head, open_list) { in snd_timer_check_slave()
286 * open a timer instance
293 struct snd_timer *timer; in snd_timer_open() local
298 if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { in snd_timer_open()
300 if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || in snd_timer_open()
301 tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) { in snd_timer_open()
302 pr_debug("ALSA: timer: invalid slave class %i\n", in snd_timer_open()
303 tid->dev_sclass); in snd_timer_open()
304 err = -EINVAL; in snd_timer_open()
308 err = -EBUSY; in snd_timer_open()
311 timeri->slave_class = tid->dev_sclass; in snd_timer_open()
312 timeri->slave_id = tid->device; in snd_timer_open()
313 timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; in snd_timer_open()
314 list_add_tail(&timeri->open_list, &snd_timer_slave_list); in snd_timer_open()
321 timer = snd_timer_find(tid); in snd_timer_open()
323 if (!timer) { in snd_timer_open()
327 timer = snd_timer_find(tid); in snd_timer_open()
330 if (!timer) { in snd_timer_open()
331 err = -ENODEV; in snd_timer_open()
334 if (!list_empty(&timer->open_list_head)) { in snd_timer_open()
336 list_entry(timer->open_list_head.next, in snd_timer_open()
338 if (t->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { in snd_timer_open()
339 err = -EBUSY; in snd_timer_open()
343 if (timer->num_instances >= timer->max_instances) { in snd_timer_open()
344 err = -EBUSY; in snd_timer_open()
347 if (!try_module_get(timer->module)) { in snd_timer_open()
348 err = -EBUSY; in snd_timer_open()
352 if (timer->card) { in snd_timer_open()
353 get_device(&timer->card->card_dev); in snd_timer_open()
354 card_dev_to_put = &timer->card->card_dev; in snd_timer_open()
357 if (list_empty(&timer->open_list_head) && timer->hw.open) { in snd_timer_open()
358 err = timer->hw.open(timer); in snd_timer_open()
360 module_put(timer->module); in snd_timer_open()
365 timeri->timer = timer; in snd_timer_open()
366 timeri->slave_class = tid->dev_sclass; in snd_timer_open()
367 timeri->slave_id = slave_id; in snd_timer_open()
369 list_add_tail(&timeri->open_list, &timer->open_list_head); in snd_timer_open()
370 timer->num_instances++; in snd_timer_open()
386 * close a timer instance
392 struct snd_timer *timer = timeri->timer; in snd_timer_close_locked() local
395 if (timer) { in snd_timer_close_locked()
396 spin_lock_irq(&timer->lock); in snd_timer_close_locked()
397 timeri->flags |= SNDRV_TIMER_IFLG_DEAD; in snd_timer_close_locked()
398 spin_unlock_irq(&timer->lock); in snd_timer_close_locked()
401 if (!list_empty(&timeri->open_list)) { in snd_timer_close_locked()
402 list_del_init(&timeri->open_list); in snd_timer_close_locked()
403 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_close_locked()
404 num_slaves--; in snd_timer_close_locked()
407 /* force to stop the timer */ in snd_timer_close_locked()
410 if (timer) { in snd_timer_close_locked()
411 timer->num_instances--; in snd_timer_close_locked()
413 spin_lock_irq(&timer->lock); in snd_timer_close_locked()
414 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { in snd_timer_close_locked()
415 spin_unlock_irq(&timer->lock); in snd_timer_close_locked()
417 spin_lock_irq(&timer->lock); in snd_timer_close_locked()
419 spin_unlock_irq(&timer->lock); in snd_timer_close_locked()
423 spin_lock(&timer->lock); in snd_timer_close_locked()
424 timeri->timer = NULL; in snd_timer_close_locked()
425 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, in snd_timer_close_locked()
427 list_move_tail(&slave->open_list, &snd_timer_slave_list); in snd_timer_close_locked()
428 timer->num_instances--; in snd_timer_close_locked()
429 slave->master = NULL; in snd_timer_close_locked()
430 slave->timer = NULL; in snd_timer_close_locked()
431 list_del_init(&slave->ack_list); in snd_timer_close_locked()
432 list_del_init(&slave->active_list); in snd_timer_close_locked()
434 spin_unlock(&timer->lock); in snd_timer_close_locked()
437 /* slave doesn't need to release timer resources below */ in snd_timer_close_locked()
438 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_close_locked()
439 timer = NULL; in snd_timer_close_locked()
442 if (timer) { in snd_timer_close_locked()
443 if (list_empty(&timer->open_list_head) && timer->hw.close) in snd_timer_close_locked()
444 timer->hw.close(timer); in snd_timer_close_locked()
446 if (timer->card) in snd_timer_close_locked()
447 *card_devp_to_put = &timer->card->card_dev; in snd_timer_close_locked()
448 module_put(timer->module); in snd_timer_close_locked()
453 * close a timer instance
471 static unsigned long snd_timer_hw_resolution(struct snd_timer *timer) in snd_timer_hw_resolution() argument
473 if (timer->hw.c_resolution) in snd_timer_hw_resolution()
474 return timer->hw.c_resolution(timer); in snd_timer_hw_resolution()
476 return timer->hw.resolution; in snd_timer_hw_resolution()
481 struct snd_timer * timer; in snd_timer_resolution() local
487 timer = timeri->timer; in snd_timer_resolution()
488 if (timer) { in snd_timer_resolution()
489 spin_lock_irqsave(&timer->lock, flags); in snd_timer_resolution()
490 ret = snd_timer_hw_resolution(timer); in snd_timer_resolution()
491 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_resolution()
499 struct snd_timer *timer = ti->timer; in snd_timer_notify1() local
511 if (timer && in snd_timer_notify1()
514 resolution = snd_timer_hw_resolution(timer); in snd_timer_notify1()
515 if (ti->ccallback) in snd_timer_notify1()
516 ti->ccallback(ti, event, &tstamp, resolution); in snd_timer_notify1()
517 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_notify1()
519 if (timer == NULL) in snd_timer_notify1()
521 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) in snd_timer_notify1()
524 list_for_each_entry(ts, &ti->slave_active_head, active_list) in snd_timer_notify1()
525 if (ts->ccallback) in snd_timer_notify1()
526 ts->ccallback(ts, event, &tstamp, resolution); in snd_timer_notify1()
529 /* start/continue a master timer */
533 struct snd_timer *timer; in snd_timer_start1() local
537 timer = timeri->timer; in snd_timer_start1()
538 if (!timer) in snd_timer_start1()
539 return -EINVAL; in snd_timer_start1()
541 spin_lock_irqsave(&timer->lock, flags); in snd_timer_start1()
542 if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) { in snd_timer_start1()
543 result = -EINVAL; in snd_timer_start1()
546 if (timer->card && timer->card->shutdown) { in snd_timer_start1()
547 result = -ENODEV; in snd_timer_start1()
550 if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | in snd_timer_start1()
552 result = -EBUSY; in snd_timer_start1()
559 if (start && !(timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) { in snd_timer_start1()
560 if ((u64)snd_timer_hw_resolution(timer) * ticks < 100000) { in snd_timer_start1()
561 result = -EINVAL; in snd_timer_start1()
567 timeri->ticks = timeri->cticks = ticks; in snd_timer_start1()
568 else if (!timeri->cticks) in snd_timer_start1()
569 timeri->cticks = 1; in snd_timer_start1()
570 timeri->pticks = 0; in snd_timer_start1()
572 list_move_tail(&timeri->active_list, &timer->active_list_head); in snd_timer_start1()
573 if (timer->running) { in snd_timer_start1()
574 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) in snd_timer_start1()
576 timer->flags |= SNDRV_TIMER_FLG_RESCHED; in snd_timer_start1()
577 timeri->flags |= SNDRV_TIMER_IFLG_START; in snd_timer_start1()
581 timer->sticks = ticks; in snd_timer_start1()
582 timer->hw.start(timer); in snd_timer_start1()
584 timer->running++; in snd_timer_start1()
585 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; in snd_timer_start1()
591 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_start1()
595 /* start/continue a slave timer */
603 if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) { in snd_timer_start_slave()
604 err = -EINVAL; in snd_timer_start_slave()
607 if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { in snd_timer_start_slave()
608 err = -EBUSY; in snd_timer_start_slave()
611 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; in snd_timer_start_slave()
612 if (timeri->master && timeri->timer) { in snd_timer_start_slave()
613 spin_lock(&timeri->timer->lock); in snd_timer_start_slave()
614 list_add_tail(&timeri->active_list, in snd_timer_start_slave()
615 &timeri->master->slave_active_head); in snd_timer_start_slave()
618 spin_unlock(&timeri->timer->lock); in snd_timer_start_slave()
626 /* stop/pause a master timer */
629 struct snd_timer *timer; in snd_timer_stop1() local
633 timer = timeri->timer; in snd_timer_stop1()
634 if (!timer) in snd_timer_stop1()
635 return -EINVAL; in snd_timer_stop1()
636 spin_lock_irqsave(&timer->lock, flags); in snd_timer_stop1()
637 list_del_init(&timeri->ack_list); in snd_timer_stop1()
638 list_del_init(&timeri->active_list); in snd_timer_stop1()
639 if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | in snd_timer_stop1()
641 result = -EBUSY; in snd_timer_stop1()
644 if (timer->card && timer->card->shutdown) in snd_timer_stop1()
647 timeri->cticks = timeri->ticks; in snd_timer_stop1()
648 timeri->pticks = 0; in snd_timer_stop1()
650 if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) && in snd_timer_stop1()
651 !(--timer->running)) { in snd_timer_stop1()
652 timer->hw.stop(timer); in snd_timer_stop1()
653 if (timer->flags & SNDRV_TIMER_FLG_RESCHED) { in snd_timer_stop1()
654 timer->flags &= ~SNDRV_TIMER_FLG_RESCHED; in snd_timer_stop1()
655 snd_timer_reschedule(timer, 0); in snd_timer_stop1()
656 if (timer->flags & SNDRV_TIMER_FLG_CHANGE) { in snd_timer_stop1()
657 timer->flags &= ~SNDRV_TIMER_FLG_CHANGE; in snd_timer_stop1()
658 timer->hw.start(timer); in snd_timer_stop1()
662 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); in snd_timer_stop1()
664 timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED; in snd_timer_stop1()
666 timeri->flags |= SNDRV_TIMER_IFLG_PAUSED; in snd_timer_stop1()
670 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_stop1()
674 /* stop/pause a slave timer */
681 running = timeri->flags & SNDRV_TIMER_IFLG_RUNNING; in snd_timer_stop_slave()
682 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; in snd_timer_stop_slave()
683 if (timeri->timer) { in snd_timer_stop_slave()
684 spin_lock(&timeri->timer->lock); in snd_timer_stop_slave()
685 list_del_init(&timeri->ack_list); in snd_timer_stop_slave()
686 list_del_init(&timeri->active_list); in snd_timer_stop_slave()
690 spin_unlock(&timeri->timer->lock); in snd_timer_stop_slave()
693 return running ? 0 : -EBUSY; in snd_timer_stop_slave()
697 * start the timer instance
702 return -EINVAL; in snd_timer_start()
703 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_start()
711 * stop the timer instance.
713 * do not call this from the timer callback!
717 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_stop()
729 /* timer can continue only after pause */ in snd_timer_continue()
730 if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED)) in snd_timer_continue()
731 return -EINVAL; in snd_timer_continue()
733 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_continue()
745 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) in snd_timer_pause()
753 * reschedule the timer
756 * when the scheduling ticks is changed set CHANGE flag to reprogram the timer.
758 static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left) in snd_timer_reschedule() argument
763 list_for_each_entry(ti, &timer->active_list_head, active_list) { in snd_timer_reschedule()
764 if (ti->flags & SNDRV_TIMER_IFLG_START) { in snd_timer_reschedule()
765 ti->flags &= ~SNDRV_TIMER_IFLG_START; in snd_timer_reschedule()
766 ti->flags |= SNDRV_TIMER_IFLG_RUNNING; in snd_timer_reschedule()
767 timer->running++; in snd_timer_reschedule()
769 if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) { in snd_timer_reschedule()
770 if (ticks > ti->cticks) in snd_timer_reschedule()
771 ticks = ti->cticks; in snd_timer_reschedule()
775 timer->flags &= ~SNDRV_TIMER_FLG_RESCHED; in snd_timer_reschedule()
778 if (ticks > timer->hw.ticks) in snd_timer_reschedule()
779 ticks = timer->hw.ticks; in snd_timer_reschedule()
781 timer->flags |= SNDRV_TIMER_FLG_CHANGE; in snd_timer_reschedule()
782 timer->sticks = ticks; in snd_timer_reschedule()
785 /* call callbacks in timer ack list */
786 static void snd_timer_process_callbacks(struct snd_timer *timer, in snd_timer_process_callbacks() argument
797 list_del_init(&ti->ack_list); in snd_timer_process_callbacks()
799 if (!(ti->flags & SNDRV_TIMER_IFLG_DEAD)) { in snd_timer_process_callbacks()
800 ticks = ti->pticks; in snd_timer_process_callbacks()
801 ti->pticks = 0; in snd_timer_process_callbacks()
802 resolution = ti->resolution; in snd_timer_process_callbacks()
803 ti->flags |= SNDRV_TIMER_IFLG_CALLBACK; in snd_timer_process_callbacks()
804 spin_unlock(&timer->lock); in snd_timer_process_callbacks()
805 if (ti->callback) in snd_timer_process_callbacks()
806 ti->callback(ti, resolution, ticks); in snd_timer_process_callbacks()
807 spin_lock(&timer->lock); in snd_timer_process_callbacks()
808 ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; in snd_timer_process_callbacks()
814 static void snd_timer_clear_callbacks(struct snd_timer *timer, in snd_timer_clear_callbacks() argument
819 spin_lock_irqsave(&timer->lock, flags); in snd_timer_clear_callbacks()
821 list_del_init(head->next); in snd_timer_clear_callbacks()
822 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_clear_callbacks()
826 * timer work
831 struct snd_timer *timer = container_of(work, struct snd_timer, task_work); in snd_timer_work() local
834 if (timer->card && timer->card->shutdown) { in snd_timer_work()
835 snd_timer_clear_callbacks(timer, &timer->sack_list_head); in snd_timer_work()
839 spin_lock_irqsave(&timer->lock, flags); in snd_timer_work()
840 snd_timer_process_callbacks(timer, &timer->sack_list_head); in snd_timer_work()
841 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_work()
845 * timer interrupt
847 * ticks_left is usually equal to timer->sticks.
850 void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) in snd_timer_interrupt() argument
858 if (timer == NULL) in snd_timer_interrupt()
861 if (timer->card && timer->card->shutdown) { in snd_timer_interrupt()
862 snd_timer_clear_callbacks(timer, &timer->ack_list_head); in snd_timer_interrupt()
866 spin_lock_irqsave(&timer->lock, flags); in snd_timer_interrupt()
869 resolution = snd_timer_hw_resolution(timer); in snd_timer_interrupt()
876 list_for_each_entry_safe(ti, tmp, &timer->active_list_head, in snd_timer_interrupt()
878 if (ti->flags & SNDRV_TIMER_IFLG_DEAD) in snd_timer_interrupt()
880 if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) in snd_timer_interrupt()
882 ti->pticks += ticks_left; in snd_timer_interrupt()
883 ti->resolution = resolution; in snd_timer_interrupt()
884 if (ti->cticks < ticks_left) in snd_timer_interrupt()
885 ti->cticks = 0; in snd_timer_interrupt()
887 ti->cticks -= ticks_left; in snd_timer_interrupt()
888 if (ti->cticks) /* not expired */ in snd_timer_interrupt()
890 if (ti->flags & SNDRV_TIMER_IFLG_AUTO) { in snd_timer_interrupt()
891 ti->cticks = ti->ticks; in snd_timer_interrupt()
893 ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; in snd_timer_interrupt()
894 --timer->running; in snd_timer_interrupt()
895 list_del_init(&ti->active_list); in snd_timer_interrupt()
897 if ((timer->hw.flags & SNDRV_TIMER_HW_WORK) || in snd_timer_interrupt()
898 (ti->flags & SNDRV_TIMER_IFLG_FAST)) in snd_timer_interrupt()
899 ack_list_head = &timer->ack_list_head; in snd_timer_interrupt()
901 ack_list_head = &timer->sack_list_head; in snd_timer_interrupt()
902 if (list_empty(&ti->ack_list)) in snd_timer_interrupt()
903 list_add_tail(&ti->ack_list, ack_list_head); in snd_timer_interrupt()
904 list_for_each_entry(ts, &ti->slave_active_head, active_list) { in snd_timer_interrupt()
905 ts->pticks = ti->pticks; in snd_timer_interrupt()
906 ts->resolution = resolution; in snd_timer_interrupt()
907 if (list_empty(&ts->ack_list)) in snd_timer_interrupt()
908 list_add_tail(&ts->ack_list, ack_list_head); in snd_timer_interrupt()
911 if (timer->flags & SNDRV_TIMER_FLG_RESCHED) in snd_timer_interrupt()
912 snd_timer_reschedule(timer, timer->sticks); in snd_timer_interrupt()
913 if (timer->running) { in snd_timer_interrupt()
914 if (timer->hw.flags & SNDRV_TIMER_HW_STOP) { in snd_timer_interrupt()
915 timer->hw.stop(timer); in snd_timer_interrupt()
916 timer->flags |= SNDRV_TIMER_FLG_CHANGE; in snd_timer_interrupt()
918 if (!(timer->hw.flags & SNDRV_TIMER_HW_AUTO) || in snd_timer_interrupt()
919 (timer->flags & SNDRV_TIMER_FLG_CHANGE)) { in snd_timer_interrupt()
920 /* restart timer */ in snd_timer_interrupt()
921 timer->flags &= ~SNDRV_TIMER_FLG_CHANGE; in snd_timer_interrupt()
922 timer->hw.start(timer); in snd_timer_interrupt()
925 timer->hw.stop(timer); in snd_timer_interrupt()
929 snd_timer_process_callbacks(timer, &timer->ack_list_head); in snd_timer_interrupt()
932 use_work = !list_empty(&timer->sack_list_head); in snd_timer_interrupt()
933 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_interrupt()
936 queue_work(system_highpri_wq, &timer->task_work); in snd_timer_interrupt()
947 struct snd_timer *timer; in snd_timer_new() local
956 return -EINVAL; in snd_timer_new()
957 if (tid->dev_class == SNDRV_TIMER_CLASS_CARD || in snd_timer_new()
958 tid->dev_class == SNDRV_TIMER_CLASS_PCM) { in snd_timer_new()
960 return -EINVAL; in snd_timer_new()
964 timer = kzalloc(sizeof(*timer), GFP_KERNEL); in snd_timer_new()
965 if (!timer) in snd_timer_new()
966 return -ENOMEM; in snd_timer_new()
967 timer->tmr_class = tid->dev_class; in snd_timer_new()
968 timer->card = card; in snd_timer_new()
969 timer->tmr_device = tid->device; in snd_timer_new()
970 timer->tmr_subdevice = tid->subdevice; in snd_timer_new()
972 strscpy(timer->id, id, sizeof(timer->id)); in snd_timer_new()
973 timer->sticks = 1; in snd_timer_new()
974 INIT_LIST_HEAD(&timer->device_list); in snd_timer_new()
975 INIT_LIST_HEAD(&timer->open_list_head); in snd_timer_new()
976 INIT_LIST_HEAD(&timer->active_list_head); in snd_timer_new()
977 INIT_LIST_HEAD(&timer->ack_list_head); in snd_timer_new()
978 INIT_LIST_HEAD(&timer->sack_list_head); in snd_timer_new()
979 spin_lock_init(&timer->lock); in snd_timer_new()
980 INIT_WORK(&timer->task_work, snd_timer_work); in snd_timer_new()
981 timer->max_instances = 1000; /* default limit per timer */ in snd_timer_new()
983 timer->module = card->module; in snd_timer_new()
984 err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); in snd_timer_new()
986 snd_timer_free(timer); in snd_timer_new()
991 *rtimer = timer; in snd_timer_new()
996 static int snd_timer_free(struct snd_timer *timer) in snd_timer_free() argument
998 if (!timer) in snd_timer_free()
1002 if (! list_empty(&timer->open_list_head)) { in snd_timer_free()
1005 pr_warn("ALSA: timer %p is busy?\n", timer); in snd_timer_free()
1006 list_for_each_safe(p, n, &timer->open_list_head) { in snd_timer_free()
1009 ti->timer = NULL; in snd_timer_free()
1012 list_del(&timer->device_list); in snd_timer_free()
1015 if (timer->private_free) in snd_timer_free()
1016 timer->private_free(timer); in snd_timer_free()
1017 kfree(timer); in snd_timer_free()
1023 struct snd_timer *timer = device->device_data; in snd_timer_dev_free() local
1024 return snd_timer_free(timer); in snd_timer_dev_free()
1029 struct snd_timer *timer = dev->device_data; in snd_timer_dev_register() local
1032 if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop)) in snd_timer_dev_register()
1033 return -ENXIO; in snd_timer_dev_register()
1034 if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && in snd_timer_dev_register()
1035 !timer->hw.resolution && timer->hw.c_resolution == NULL) in snd_timer_dev_register()
1036 return -EINVAL; in snd_timer_dev_register()
1040 if (timer1->tmr_class > timer->tmr_class) in snd_timer_dev_register()
1042 if (timer1->tmr_class < timer->tmr_class) in snd_timer_dev_register()
1044 if (timer1->card && timer->card) { in snd_timer_dev_register()
1045 if (timer1->card->number > timer->card->number) in snd_timer_dev_register()
1047 if (timer1->card->number < timer->card->number) in snd_timer_dev_register()
1050 if (timer1->tmr_device > timer->tmr_device) in snd_timer_dev_register()
1052 if (timer1->tmr_device < timer->tmr_device) in snd_timer_dev_register()
1054 if (timer1->tmr_subdevice > timer->tmr_subdevice) in snd_timer_dev_register()
1056 if (timer1->tmr_subdevice < timer->tmr_subdevice) in snd_timer_dev_register()
1060 return -EBUSY; in snd_timer_dev_register()
1062 list_add_tail(&timer->device_list, &timer1->device_list); in snd_timer_dev_register()
1069 struct snd_timer *timer = device->device_data; in snd_timer_dev_disconnect() local
1073 list_del_init(&timer->device_list); in snd_timer_dev_disconnect()
1075 list_for_each_entry(ti, &timer->open_list_head, open_list) { in snd_timer_dev_disconnect()
1076 if (ti->disconnect) in snd_timer_dev_disconnect()
1077 ti->disconnect(ti); in snd_timer_dev_disconnect()
1083 void snd_timer_notify(struct snd_timer *timer, int event, struct timespec64 *tstamp) in snd_timer_notify() argument
1089 if (timer->card && timer->card->shutdown) in snd_timer_notify()
1091 if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) in snd_timer_notify()
1096 spin_lock_irqsave(&timer->lock, flags); in snd_timer_notify()
1100 resolution = snd_timer_hw_resolution(timer); in snd_timer_notify()
1101 list_for_each_entry(ti, &timer->active_list_head, active_list) { in snd_timer_notify()
1102 if (ti->ccallback) in snd_timer_notify()
1103 ti->ccallback(ti, event, tstamp, resolution); in snd_timer_notify()
1104 list_for_each_entry(ts, &ti->slave_active_head, active_list) in snd_timer_notify()
1105 if (ts->ccallback) in snd_timer_notify()
1106 ts->ccallback(ts, event, tstamp, resolution); in snd_timer_notify()
1108 spin_unlock_irqrestore(&timer->lock, flags); in snd_timer_notify()
1121 tid.card = -1; in snd_timer_global_new()
1128 int snd_timer_global_free(struct snd_timer *timer) in snd_timer_global_free() argument
1130 return snd_timer_free(timer); in snd_timer_global_free()
1134 int snd_timer_global_register(struct snd_timer *timer) in snd_timer_global_register() argument
1139 dev.device_data = timer; in snd_timer_global_register()
1145 * System timer
1160 struct snd_timer *timer = priv->snd_timer; in snd_timer_s_function() local
1162 if (time_after(jiff, priv->last_expires)) in snd_timer_s_function()
1163 priv->correction += (long)jiff - (long)priv->last_expires; in snd_timer_s_function()
1164 snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies); in snd_timer_s_function()
1167 static int snd_timer_s_start(struct snd_timer * timer) in snd_timer_s_start() argument
1172 priv = (struct snd_timer_system_private *) timer->private_data; in snd_timer_s_start()
1173 njiff = (priv->last_jiffies = jiffies); in snd_timer_s_start()
1174 if (priv->correction > timer->sticks - 1) { in snd_timer_s_start()
1175 priv->correction -= timer->sticks - 1; in snd_timer_s_start()
1178 njiff += timer->sticks - priv->correction; in snd_timer_s_start()
1179 priv->correction = 0; in snd_timer_s_start()
1181 priv->last_expires = njiff; in snd_timer_s_start()
1182 mod_timer(&priv->tlist, njiff); in snd_timer_s_start()
1186 static int snd_timer_s_stop(struct snd_timer * timer) in snd_timer_s_stop() argument
1191 priv = (struct snd_timer_system_private *) timer->private_data; in snd_timer_s_stop()
1192 del_timer(&priv->tlist); in snd_timer_s_stop()
1194 if (time_before(jiff, priv->last_expires)) in snd_timer_s_stop()
1195 timer->sticks = priv->last_expires - jiff; in snd_timer_s_stop()
1197 timer->sticks = 1; in snd_timer_s_stop()
1198 priv->correction = 0; in snd_timer_s_stop()
1202 static int snd_timer_s_close(struct snd_timer *timer) in snd_timer_s_close() argument
1206 priv = (struct snd_timer_system_private *)timer->private_data; in snd_timer_s_close()
1207 del_timer_sync(&priv->tlist); in snd_timer_s_close()
1221 static void snd_timer_free_system(struct snd_timer *timer) in snd_timer_free_system() argument
1223 kfree(timer->private_data); in snd_timer_free_system()
1228 struct snd_timer *timer; in snd_timer_register_system() local
1232 err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer); in snd_timer_register_system()
1235 strcpy(timer->name, "system timer"); in snd_timer_register_system()
1236 timer->hw = snd_timer_system; in snd_timer_register_system()
1239 snd_timer_free(timer); in snd_timer_register_system()
1240 return -ENOMEM; in snd_timer_register_system()
1242 priv->snd_timer = timer; in snd_timer_register_system()
1243 timer_setup(&priv->tlist, snd_timer_s_function, 0); in snd_timer_register_system()
1244 timer->private_data = priv; in snd_timer_register_system()
1245 timer->private_free = snd_timer_free_system; in snd_timer_register_system()
1246 return snd_timer_global_register(timer); in snd_timer_register_system()
1257 struct snd_timer *timer; in snd_timer_proc_read() local
1262 list_for_each_entry(timer, &snd_timer_list, device_list) { in snd_timer_proc_read()
1263 if (timer->card && timer->card->shutdown) in snd_timer_proc_read()
1265 switch (timer->tmr_class) { in snd_timer_proc_read()
1267 snd_iprintf(buffer, "G%i: ", timer->tmr_device); in snd_timer_proc_read()
1270 snd_iprintf(buffer, "C%i-%i: ", in snd_timer_proc_read()
1271 timer->card->number, timer->tmr_device); in snd_timer_proc_read()
1274 snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, in snd_timer_proc_read()
1275 timer->tmr_device, timer->tmr_subdevice); in snd_timer_proc_read()
1278 snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, in snd_timer_proc_read()
1279 timer->card ? timer->card->number : -1, in snd_timer_proc_read()
1280 timer->tmr_device, timer->tmr_subdevice); in snd_timer_proc_read()
1282 snd_iprintf(buffer, "%s :", timer->name); in snd_timer_proc_read()
1283 spin_lock_irq(&timer->lock); in snd_timer_proc_read()
1284 resolution = snd_timer_hw_resolution(timer); in snd_timer_proc_read()
1285 spin_unlock_irq(&timer->lock); in snd_timer_proc_read()
1290 timer->hw.ticks); in snd_timer_proc_read()
1291 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) in snd_timer_proc_read()
1294 list_for_each_entry(ti, &timer->open_list_head, open_list) in snd_timer_proc_read()
1296 ti->owner ? ti->owner : "unknown", in snd_timer_proc_read()
1297 (ti->flags & (SNDRV_TIMER_IFLG_START | in snd_timer_proc_read()
1312 entry->c.text.read = snd_timer_proc_read; in snd_timer_proc_init()
1338 struct snd_timer_user *tu = timeri->callback_data; in snd_timer_user_interrupt()
1342 spin_lock(&tu->qlock); in snd_timer_user_interrupt()
1343 if (tu->qused > 0) { in snd_timer_user_interrupt()
1344 prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; in snd_timer_user_interrupt()
1345 r = &tu->queue[prev]; in snd_timer_user_interrupt()
1346 if (r->resolution == resolution) { in snd_timer_user_interrupt()
1347 r->ticks += ticks; in snd_timer_user_interrupt()
1351 if (tu->qused >= tu->queue_size) { in snd_timer_user_interrupt()
1352 tu->overrun++; in snd_timer_user_interrupt()
1354 r = &tu->queue[tu->qtail++]; in snd_timer_user_interrupt()
1355 tu->qtail %= tu->queue_size; in snd_timer_user_interrupt()
1356 r->resolution = resolution; in snd_timer_user_interrupt()
1357 r->ticks = ticks; in snd_timer_user_interrupt()
1358 tu->qused++; in snd_timer_user_interrupt()
1361 spin_unlock(&tu->qlock); in snd_timer_user_interrupt()
1362 snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); in snd_timer_user_interrupt()
1363 wake_up(&tu->qchange_sleep); in snd_timer_user_interrupt()
1369 if (tu->qused >= tu->queue_size) { in snd_timer_user_append_to_tqueue()
1370 tu->overrun++; in snd_timer_user_append_to_tqueue()
1372 memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread)); in snd_timer_user_append_to_tqueue()
1373 tu->qtail %= tu->queue_size; in snd_timer_user_append_to_tqueue()
1374 tu->qused++; in snd_timer_user_append_to_tqueue()
1383 struct snd_timer_user *tu = timeri->callback_data; in snd_timer_user_ccallback()
1389 tu->tstamp = *tstamp; in snd_timer_user_ccallback()
1390 if ((tu->filter & (1 << event)) == 0 || !tu->tread) in snd_timer_user_ccallback()
1394 r1.tstamp_sec = tstamp->tv_sec; in snd_timer_user_ccallback()
1395 r1.tstamp_nsec = tstamp->tv_nsec; in snd_timer_user_ccallback()
1397 spin_lock_irqsave(&tu->qlock, flags); in snd_timer_user_ccallback()
1399 spin_unlock_irqrestore(&tu->qlock, flags); in snd_timer_user_ccallback()
1400 snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); in snd_timer_user_ccallback()
1401 wake_up(&tu->qchange_sleep); in snd_timer_user_ccallback()
1406 struct snd_timer_user *tu = timeri->callback_data; in snd_timer_user_disconnect()
1408 tu->disconnected = true; in snd_timer_user_disconnect()
1409 wake_up(&tu->qchange_sleep); in snd_timer_user_disconnect()
1416 struct snd_timer_user *tu = timeri->callback_data; in snd_timer_user_tinterrupt()
1423 spin_lock(&tu->qlock); in snd_timer_user_tinterrupt()
1424 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | in snd_timer_user_tinterrupt()
1426 spin_unlock(&tu->qlock); in snd_timer_user_tinterrupt()
1429 if (tu->last_resolution != resolution || ticks > 0) { in snd_timer_user_tinterrupt()
1435 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && in snd_timer_user_tinterrupt()
1436 tu->last_resolution != resolution) { in snd_timer_user_tinterrupt()
1442 tu->last_resolution = resolution; in snd_timer_user_tinterrupt()
1445 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0) in snd_timer_user_tinterrupt()
1449 if (tu->qused > 0) { in snd_timer_user_tinterrupt()
1450 prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; in snd_timer_user_tinterrupt()
1451 r = &tu->tqueue[prev]; in snd_timer_user_tinterrupt()
1452 if (r->event == SNDRV_TIMER_EVENT_TICK) { in snd_timer_user_tinterrupt()
1453 r->tstamp_sec = tstamp.tv_sec; in snd_timer_user_tinterrupt()
1454 r->tstamp_nsec = tstamp.tv_nsec; in snd_timer_user_tinterrupt()
1455 r->val += ticks; in snd_timer_user_tinterrupt()
1467 spin_unlock(&tu->qlock); in snd_timer_user_tinterrupt()
1470 snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); in snd_timer_user_tinterrupt()
1471 wake_up(&tu->qchange_sleep); in snd_timer_user_tinterrupt()
1479 if (tu->tread) { in realloc_user_queue()
1482 return -ENOMEM; in realloc_user_queue()
1486 return -ENOMEM; in realloc_user_queue()
1489 spin_lock_irq(&tu->qlock); in realloc_user_queue()
1490 kfree(tu->queue); in realloc_user_queue()
1491 kfree(tu->tqueue); in realloc_user_queue()
1492 tu->queue_size = size; in realloc_user_queue()
1493 tu->queue = queue; in realloc_user_queue()
1494 tu->tqueue = tqueue; in realloc_user_queue()
1495 tu->qhead = tu->qtail = tu->qused = 0; in realloc_user_queue()
1496 spin_unlock_irq(&tu->qlock); in realloc_user_queue()
1512 return -ENOMEM; in snd_timer_user_open()
1513 spin_lock_init(&tu->qlock); in snd_timer_user_open()
1514 init_waitqueue_head(&tu->qchange_sleep); in snd_timer_user_open()
1515 mutex_init(&tu->ioctl_lock); in snd_timer_user_open()
1516 tu->ticks = 1; in snd_timer_user_open()
1519 return -ENOMEM; in snd_timer_user_open()
1521 file->private_data = tu; in snd_timer_user_open()
1529 if (file->private_data) { in snd_timer_user_release()
1530 tu = file->private_data; in snd_timer_user_release()
1531 file->private_data = NULL; in snd_timer_user_release()
1532 mutex_lock(&tu->ioctl_lock); in snd_timer_user_release()
1533 if (tu->timeri) { in snd_timer_user_release()
1534 snd_timer_close(tu->timeri); in snd_timer_user_release()
1535 snd_timer_instance_free(tu->timeri); in snd_timer_user_release()
1537 mutex_unlock(&tu->ioctl_lock); in snd_timer_user_release()
1538 snd_fasync_free(tu->fasync); in snd_timer_user_release()
1539 kfree(tu->queue); in snd_timer_user_release()
1540 kfree(tu->tqueue); in snd_timer_user_release()
1548 id->dev_class = SNDRV_TIMER_CLASS_NONE; in snd_timer_user_zero_id()
1549 id->dev_sclass = SNDRV_TIMER_SCLASS_NONE; in snd_timer_user_zero_id()
1550 id->card = -1; in snd_timer_user_zero_id()
1551 id->device = -1; in snd_timer_user_zero_id()
1552 id->subdevice = -1; in snd_timer_user_zero_id()
1555 static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *timer) in snd_timer_user_copy_id() argument
1557 id->dev_class = timer->tmr_class; in snd_timer_user_copy_id()
1558 id->dev_sclass = SNDRV_TIMER_SCLASS_NONE; in snd_timer_user_copy_id()
1559 id->card = timer->card ? timer->card->number : -1; in snd_timer_user_copy_id()
1560 id->device = timer->tmr_device; in snd_timer_user_copy_id()
1561 id->subdevice = timer->tmr_subdevice; in snd_timer_user_copy_id()
1567 struct snd_timer *timer; in snd_timer_user_next_device() local
1571 return -EFAULT; in snd_timer_user_next_device()
1577 timer = list_entry(snd_timer_list.next, in snd_timer_user_next_device()
1579 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1586 timer = list_entry(p, struct snd_timer, device_list); in snd_timer_user_next_device()
1587 if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { in snd_timer_user_next_device()
1588 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1591 if (timer->tmr_device >= id.device) { in snd_timer_user_next_device()
1592 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1614 timer = list_entry(p, struct snd_timer, device_list); in snd_timer_user_next_device()
1615 if (timer->tmr_class > id.dev_class) { in snd_timer_user_next_device()
1616 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1619 if (timer->tmr_class < id.dev_class) in snd_timer_user_next_device()
1621 if (timer->card->number > id.card) { in snd_timer_user_next_device()
1622 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1625 if (timer->card->number < id.card) in snd_timer_user_next_device()
1627 if (timer->tmr_device > id.device) { in snd_timer_user_next_device()
1628 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1631 if (timer->tmr_device < id.device) in snd_timer_user_next_device()
1633 if (timer->tmr_subdevice > id.subdevice) { in snd_timer_user_next_device()
1634 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1637 if (timer->tmr_subdevice < id.subdevice) in snd_timer_user_next_device()
1639 snd_timer_user_copy_id(&id, timer); in snd_timer_user_next_device()
1651 return -EFAULT; in snd_timer_user_next_device()
1668 tid = ginfo->tid; in snd_timer_user_ginfo()
1670 ginfo->tid = tid; in snd_timer_user_ginfo()
1674 ginfo->card = t->card ? t->card->number : -1; in snd_timer_user_ginfo()
1675 if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) in snd_timer_user_ginfo()
1676 ginfo->flags |= SNDRV_TIMER_FLG_SLAVE; in snd_timer_user_ginfo()
1677 strscpy(ginfo->id, t->id, sizeof(ginfo->id)); in snd_timer_user_ginfo()
1678 strscpy(ginfo->name, t->name, sizeof(ginfo->name)); in snd_timer_user_ginfo()
1679 spin_lock_irq(&t->lock); in snd_timer_user_ginfo()
1680 ginfo->resolution = snd_timer_hw_resolution(t); in snd_timer_user_ginfo()
1681 spin_unlock_irq(&t->lock); in snd_timer_user_ginfo()
1682 if (t->hw.resolution_min > 0) { in snd_timer_user_ginfo()
1683 ginfo->resolution_min = t->hw.resolution_min; in snd_timer_user_ginfo()
1684 ginfo->resolution_max = t->hw.resolution_max; in snd_timer_user_ginfo()
1686 list_for_each(p, &t->open_list_head) { in snd_timer_user_ginfo()
1687 ginfo->clients++; in snd_timer_user_ginfo()
1690 err = -ENODEV; in snd_timer_user_ginfo()
1694 err = -EFAULT; in snd_timer_user_ginfo()
1705 t = snd_timer_find(&gparams->tid); in timer_set_gparams()
1707 err = -ENODEV; in timer_set_gparams()
1710 if (!list_empty(&t->open_list_head)) { in timer_set_gparams()
1711 err = -EBUSY; in timer_set_gparams()
1714 if (!t->hw.set_period) { in timer_set_gparams()
1715 err = -ENOSYS; in timer_set_gparams()
1718 err = t->hw.set_period(t, gparams->period_num, gparams->period_den); in timer_set_gparams()
1730 return -EFAULT; in snd_timer_user_gparams()
1743 return -EFAULT; in snd_timer_user_gstatus()
1750 spin_lock_irq(&t->lock); in snd_timer_user_gstatus()
1752 if (t->hw.precise_resolution) { in snd_timer_user_gstatus()
1753 t->hw.precise_resolution(t, &gstatus.resolution_num, in snd_timer_user_gstatus()
1759 spin_unlock_irq(&t->lock); in snd_timer_user_gstatus()
1761 err = -ENODEV; in snd_timer_user_gstatus()
1765 err = -EFAULT; in snd_timer_user_gstatus()
1777 tu = file->private_data; in snd_timer_user_tselect()
1778 if (tu->timeri) { in snd_timer_user_tselect()
1779 snd_timer_close(tu->timeri); in snd_timer_user_tselect()
1780 snd_timer_instance_free(tu->timeri); in snd_timer_user_tselect()
1781 tu->timeri = NULL; in snd_timer_user_tselect()
1784 err = -EFAULT; in snd_timer_user_tselect()
1787 sprintf(str, "application %i", current->pid); in snd_timer_user_tselect()
1790 tu->timeri = snd_timer_instance_new(str); in snd_timer_user_tselect()
1791 if (!tu->timeri) { in snd_timer_user_tselect()
1792 err = -ENOMEM; in snd_timer_user_tselect()
1796 tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; in snd_timer_user_tselect()
1797 tu->timeri->callback = tu->tread in snd_timer_user_tselect()
1799 tu->timeri->ccallback = snd_timer_user_ccallback; in snd_timer_user_tselect()
1800 tu->timeri->callback_data = (void *)tu; in snd_timer_user_tselect()
1801 tu->timeri->disconnect = snd_timer_user_disconnect; in snd_timer_user_tselect()
1803 err = snd_timer_open(tu->timeri, &tselect.id, current->pid); in snd_timer_user_tselect()
1805 snd_timer_instance_free(tu->timeri); in snd_timer_user_tselect()
1806 tu->timeri = NULL; in snd_timer_user_tselect()
1821 tu = file->private_data; in snd_timer_user_info()
1822 if (!tu->timeri) in snd_timer_user_info()
1823 return -EBADFD; in snd_timer_user_info()
1824 t = tu->timeri->timer; in snd_timer_user_info()
1826 return -EBADFD; in snd_timer_user_info()
1830 return -ENOMEM; in snd_timer_user_info()
1831 info->card = t->card ? t->card->number : -1; in snd_timer_user_info()
1832 if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) in snd_timer_user_info()
1833 info->flags |= SNDRV_TIMER_FLG_SLAVE; in snd_timer_user_info()
1834 strscpy(info->id, t->id, sizeof(info->id)); in snd_timer_user_info()
1835 strscpy(info->name, t->name, sizeof(info->name)); in snd_timer_user_info()
1836 spin_lock_irq(&t->lock); in snd_timer_user_info()
1837 info->resolution = snd_timer_hw_resolution(t); in snd_timer_user_info()
1838 spin_unlock_irq(&t->lock); in snd_timer_user_info()
1840 err = -EFAULT; in snd_timer_user_info()
1853 tu = file->private_data; in snd_timer_user_params()
1854 if (!tu->timeri) in snd_timer_user_params()
1855 return -EBADFD; in snd_timer_user_params()
1856 t = tu->timeri->timer; in snd_timer_user_params()
1858 return -EBADFD; in snd_timer_user_params()
1860 return -EFAULT; in snd_timer_user_params()
1861 if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { in snd_timer_user_params()
1865 err = -EINVAL; in snd_timer_user_params()
1870 resolution = snd_timer_resolution(tu->timeri); in snd_timer_user_params()
1873 err = -EINVAL; in snd_timer_user_params()
1879 err = -EINVAL; in snd_timer_user_params()
1896 err = -EINVAL; in snd_timer_user_params()
1899 snd_timer_stop(tu->timeri); in snd_timer_user_params()
1900 spin_lock_irq(&t->lock); in snd_timer_user_params()
1901 tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO| in snd_timer_user_params()
1905 tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO; in snd_timer_user_params()
1907 tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE; in snd_timer_user_params()
1909 tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; in snd_timer_user_params()
1910 spin_unlock_irq(&t->lock); in snd_timer_user_params()
1912 (unsigned int)tu->queue_size != params.queue_size) { in snd_timer_user_params()
1917 spin_lock_irq(&tu->qlock); in snd_timer_user_params()
1918 tu->qhead = tu->qtail = tu->qused = 0; in snd_timer_user_params()
1919 if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { in snd_timer_user_params()
1920 if (tu->tread) { in snd_timer_user_params()
1929 struct snd_timer_read *r = &tu->queue[0]; in snd_timer_user_params()
1930 r->resolution = 0; in snd_timer_user_params()
1931 r->ticks = 0; in snd_timer_user_params()
1932 tu->qused++; in snd_timer_user_params()
1933 tu->qtail++; in snd_timer_user_params()
1936 tu->filter = params.filter; in snd_timer_user_params()
1937 tu->ticks = params.ticks; in snd_timer_user_params()
1938 spin_unlock_irq(&tu->qlock); in snd_timer_user_params()
1942 return -EFAULT; in snd_timer_user_params()
1952 tu = file->private_data; in snd_timer_user_status32()
1953 if (!tu->timeri) in snd_timer_user_status32()
1954 return -EBADFD; in snd_timer_user_status32()
1956 status.tstamp_sec = tu->tstamp.tv_sec; in snd_timer_user_status32()
1957 status.tstamp_nsec = tu->tstamp.tv_nsec; in snd_timer_user_status32()
1958 status.resolution = snd_timer_resolution(tu->timeri); in snd_timer_user_status32()
1959 status.lost = tu->timeri->lost; in snd_timer_user_status32()
1960 status.overrun = tu->overrun; in snd_timer_user_status32()
1961 spin_lock_irq(&tu->qlock); in snd_timer_user_status32()
1962 status.queue = tu->qused; in snd_timer_user_status32()
1963 spin_unlock_irq(&tu->qlock); in snd_timer_user_status32()
1965 return -EFAULT; in snd_timer_user_status32()
1975 tu = file->private_data; in snd_timer_user_status64()
1976 if (!tu->timeri) in snd_timer_user_status64()
1977 return -EBADFD; in snd_timer_user_status64()
1979 status.tstamp_sec = tu->tstamp.tv_sec; in snd_timer_user_status64()
1980 status.tstamp_nsec = tu->tstamp.tv_nsec; in snd_timer_user_status64()
1981 status.resolution = snd_timer_resolution(tu->timeri); in snd_timer_user_status64()
1982 status.lost = tu->timeri->lost; in snd_timer_user_status64()
1983 status.overrun = tu->overrun; in snd_timer_user_status64()
1984 spin_lock_irq(&tu->qlock); in snd_timer_user_status64()
1985 status.queue = tu->qused; in snd_timer_user_status64()
1986 spin_unlock_irq(&tu->qlock); in snd_timer_user_status64()
1988 return -EFAULT; in snd_timer_user_status64()
1997 tu = file->private_data; in snd_timer_user_start()
1998 if (!tu->timeri) in snd_timer_user_start()
1999 return -EBADFD; in snd_timer_user_start()
2000 snd_timer_stop(tu->timeri); in snd_timer_user_start()
2001 tu->timeri->lost = 0; in snd_timer_user_start()
2002 tu->last_resolution = 0; in snd_timer_user_start()
2003 err = snd_timer_start(tu->timeri, tu->ticks); in snd_timer_user_start()
2014 tu = file->private_data; in snd_timer_user_stop()
2015 if (!tu->timeri) in snd_timer_user_stop()
2016 return -EBADFD; in snd_timer_user_stop()
2017 err = snd_timer_stop(tu->timeri); in snd_timer_user_stop()
2028 tu = file->private_data; in snd_timer_user_continue()
2029 if (!tu->timeri) in snd_timer_user_continue()
2030 return -EBADFD; in snd_timer_user_continue()
2031 /* start timer instead of continue if it's not used before */ in snd_timer_user_continue()
2032 if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED)) in snd_timer_user_continue()
2034 tu->timeri->lost = 0; in snd_timer_user_continue()
2035 err = snd_timer_continue(tu->timeri); in snd_timer_user_continue()
2046 tu = file->private_data; in snd_timer_user_pause()
2047 if (!tu->timeri) in snd_timer_user_pause()
2048 return -EBADFD; in snd_timer_user_pause()
2049 err = snd_timer_pause(tu->timeri); in snd_timer_user_pause()
2061 if (tu->timeri) /* too late */ in snd_timer_user_tread()
2062 return -EBUSY; in snd_timer_user_tread()
2064 return -EFAULT; in snd_timer_user_tread()
2066 old_tread = tu->tread; in snd_timer_user_tread()
2069 tu->tread = TREAD_FORMAT_NONE; in snd_timer_user_tread()
2072 tu->tread = TREAD_FORMAT_TIME64; in snd_timer_user_tread()
2074 tu->tread = TREAD_FORMAT_TIME32; in snd_timer_user_tread()
2076 if (tu->tread != old_tread && in snd_timer_user_tread()
2077 realloc_user_queue(tu, tu->queue_size) < 0) { in snd_timer_user_tread()
2078 tu->tread = old_tread; in snd_timer_user_tread()
2079 return -ENOMEM; in snd_timer_user_tread()
2099 tu = file->private_data; in __snd_timer_user_ioctl()
2102 return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0; in __snd_timer_user_ioctl()
2137 return -ENOTTY; in __snd_timer_user_ioctl()
2143 struct snd_timer_user *tu = file->private_data; in snd_timer_user_ioctl()
2146 mutex_lock(&tu->ioctl_lock); in snd_timer_user_ioctl()
2148 mutex_unlock(&tu->ioctl_lock); in snd_timer_user_ioctl()
2156 tu = file->private_data; in snd_timer_user_fasync()
2157 return snd_fasync_helper(fd, file, on, &tu->fasync); in snd_timer_user_fasync()
2170 tu = file->private_data; in snd_timer_user_read()
2171 switch (tu->tread) { in snd_timer_user_read()
2183 return -ENOTSUPP; in snd_timer_user_read()
2186 mutex_lock(&tu->ioctl_lock); in snd_timer_user_read()
2187 spin_lock_irq(&tu->qlock); in snd_timer_user_read()
2188 while ((long)count - result >= unit) { in snd_timer_user_read()
2189 while (!tu->qused) { in snd_timer_user_read()
2192 if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) { in snd_timer_user_read()
2193 err = -EAGAIN; in snd_timer_user_read()
2199 add_wait_queue(&tu->qchange_sleep, &wait); in snd_timer_user_read()
2201 spin_unlock_irq(&tu->qlock); in snd_timer_user_read()
2202 mutex_unlock(&tu->ioctl_lock); in snd_timer_user_read()
2204 mutex_lock(&tu->ioctl_lock); in snd_timer_user_read()
2205 spin_lock_irq(&tu->qlock); in snd_timer_user_read()
2207 remove_wait_queue(&tu->qchange_sleep, &wait); in snd_timer_user_read()
2209 if (tu->disconnected) { in snd_timer_user_read()
2210 err = -ENODEV; in snd_timer_user_read()
2214 err = -ERESTARTSYS; in snd_timer_user_read()
2219 qhead = tu->qhead++; in snd_timer_user_read()
2220 tu->qhead %= tu->queue_size; in snd_timer_user_read()
2221 tu->qused--; in snd_timer_user_read()
2222 spin_unlock_irq(&tu->qlock); in snd_timer_user_read()
2224 tread = &tu->tqueue[qhead]; in snd_timer_user_read()
2226 switch (tu->tread) { in snd_timer_user_read()
2230 err = -EFAULT; in snd_timer_user_read()
2235 .event = tread->event, in snd_timer_user_read()
2236 .tstamp_sec = tread->tstamp_sec, in snd_timer_user_read()
2237 .tstamp_nsec = tread->tstamp_nsec, in snd_timer_user_read()
2238 .val = tread->val, in snd_timer_user_read()
2242 err = -EFAULT; in snd_timer_user_read()
2245 if (copy_to_user(buffer, &tu->queue[qhead], in snd_timer_user_read()
2247 err = -EFAULT; in snd_timer_user_read()
2250 err = -ENOTSUPP; in snd_timer_user_read()
2254 spin_lock_irq(&tu->qlock); in snd_timer_user_read()
2261 spin_unlock_irq(&tu->qlock); in snd_timer_user_read()
2262 mutex_unlock(&tu->ioctl_lock); in snd_timer_user_read()
2271 tu = file->private_data; in snd_timer_user_poll()
2273 poll_wait(file, &tu->qchange_sleep, wait); in snd_timer_user_poll()
2276 spin_lock_irq(&tu->qlock); in snd_timer_user_poll()
2277 if (tu->qused) in snd_timer_user_poll()
2279 if (tu->disconnected) in snd_timer_user_poll()
2281 spin_unlock_irq(&tu->qlock); in snd_timer_user_poll()
2305 /* unregister the system timer */
2308 struct snd_timer *timer, *n; in snd_timer_free_all() local
2310 list_for_each_entry_safe(timer, n, &snd_timer_list, device_list) in snd_timer_free_all()
2311 snd_timer_free(timer); in snd_timer_free_all()
2327 dev_set_name(timer_dev, "timer"); in alsa_timer_init()
2330 snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, in alsa_timer_init()
2331 "system timer"); in alsa_timer_init()
2336 pr_err("ALSA: unable to register system timer (%i)\n", err); in alsa_timer_init()
2343 pr_err("ALSA: unable to register timer device (%i)\n", err); in alsa_timer_init()
2363 snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1); in alsa_timer_exit()