@@ -318,8 +318,6 @@ int snd_timer_open(struct snd_timer_instance **ti,
318
318
return 0 ;
319
319
}
320
320
321
- static int _snd_timer_stop (struct snd_timer_instance * timeri , int event );
322
-
323
321
/*
324
322
* close a timer instance
325
323
*/
@@ -408,7 +406,6 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
408
406
static void snd_timer_notify1 (struct snd_timer_instance * ti , int event )
409
407
{
410
408
struct snd_timer * timer ;
411
- unsigned long flags ;
412
409
unsigned long resolution = 0 ;
413
410
struct snd_timer_instance * ts ;
414
411
struct timespec tstamp ;
@@ -432,34 +429,66 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
432
429
return ;
433
430
if (timer -> hw .flags & SNDRV_TIMER_HW_SLAVE )
434
431
return ;
435
- spin_lock_irqsave (& timer -> lock , flags );
436
432
list_for_each_entry (ts , & ti -> slave_active_head , active_list )
437
433
if (ts -> ccallback )
438
434
ts -> ccallback (ts , event + 100 , & tstamp , resolution );
439
- spin_unlock_irqrestore (& timer -> lock , flags );
440
435
}
441
436
442
- static int snd_timer_start1 (struct snd_timer * timer , struct snd_timer_instance * timeri ,
443
- unsigned long sticks )
437
+ /* start/continue a master timer */
438
+ static int snd_timer_start1 (struct snd_timer_instance * timeri ,
439
+ bool start , unsigned long ticks )
444
440
{
441
+ struct snd_timer * timer ;
442
+ int result ;
443
+ unsigned long flags ;
444
+
445
+ timer = timeri -> timer ;
446
+ if (!timer )
447
+ return - EINVAL ;
448
+
449
+ spin_lock_irqsave (& timer -> lock , flags );
450
+ if (timer -> card && timer -> card -> shutdown ) {
451
+ result = - ENODEV ;
452
+ goto unlock ;
453
+ }
454
+ if (timeri -> flags & (SNDRV_TIMER_IFLG_RUNNING |
455
+ SNDRV_TIMER_IFLG_START )) {
456
+ result = - EBUSY ;
457
+ goto unlock ;
458
+ }
459
+
460
+ if (start )
461
+ timeri -> ticks = timeri -> cticks = ticks ;
462
+ else if (!timeri -> cticks )
463
+ timeri -> cticks = 1 ;
464
+ timeri -> pticks = 0 ;
465
+
445
466
list_move_tail (& timeri -> active_list , & timer -> active_list_head );
446
467
if (timer -> running ) {
447
468
if (timer -> hw .flags & SNDRV_TIMER_HW_SLAVE )
448
469
goto __start_now ;
449
470
timer -> flags |= SNDRV_TIMER_FLG_RESCHED ;
450
471
timeri -> flags |= SNDRV_TIMER_IFLG_START ;
451
- return 1 ; /* delayed start */
472
+ result = 1 ; /* delayed start */
452
473
} else {
453
- timer -> sticks = sticks ;
474
+ if (start )
475
+ timer -> sticks = ticks ;
454
476
timer -> hw .start (timer );
455
477
__start_now :
456
478
timer -> running ++ ;
457
479
timeri -> flags |= SNDRV_TIMER_IFLG_RUNNING ;
458
- return 0 ;
480
+ result = 0 ;
459
481
}
482
+ snd_timer_notify1 (timeri , start ? SNDRV_TIMER_EVENT_START :
483
+ SNDRV_TIMER_EVENT_CONTINUE );
484
+ unlock :
485
+ spin_unlock_irqrestore (& timer -> lock , flags );
486
+ return result ;
460
487
}
461
488
462
- static int snd_timer_start_slave (struct snd_timer_instance * timeri )
489
+ /* start/continue a slave timer */
490
+ static int snd_timer_start_slave (struct snd_timer_instance * timeri ,
491
+ bool start )
463
492
{
464
493
unsigned long flags ;
465
494
@@ -473,88 +502,37 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
473
502
spin_lock (& timeri -> timer -> lock );
474
503
list_add_tail (& timeri -> active_list ,
475
504
& timeri -> master -> slave_active_head );
505
+ snd_timer_notify1 (timeri , start ? SNDRV_TIMER_EVENT_START :
506
+ SNDRV_TIMER_EVENT_CONTINUE );
476
507
spin_unlock (& timeri -> timer -> lock );
477
508
}
478
509
spin_unlock_irqrestore (& slave_active_lock , flags );
479
510
return 1 ; /* delayed start */
480
511
}
481
512
482
- /*
483
- * start the timer instance
484
- */
485
- int snd_timer_start (struct snd_timer_instance * timeri , unsigned int ticks )
513
+ /* stop/pause a master timer */
514
+ static int snd_timer_stop1 (struct snd_timer_instance * timeri , bool stop )
486
515
{
487
516
struct snd_timer * timer ;
488
- int result = - EINVAL ;
517
+ int result = 0 ;
489
518
unsigned long flags ;
490
519
491
- if (timeri == NULL || ticks < 1 )
492
- return - EINVAL ;
493
- if (timeri -> flags & SNDRV_TIMER_IFLG_SLAVE ) {
494
- result = snd_timer_start_slave (timeri );
495
- if (result >= 0 )
496
- snd_timer_notify1 (timeri , SNDRV_TIMER_EVENT_START );
497
- return result ;
498
- }
499
- timer = timeri -> timer ;
500
- if (timer == NULL )
501
- return - EINVAL ;
502
- if (timer -> card && timer -> card -> shutdown )
503
- return - ENODEV ;
504
- spin_lock_irqsave (& timer -> lock , flags );
505
- if (timeri -> flags & (SNDRV_TIMER_IFLG_RUNNING |
506
- SNDRV_TIMER_IFLG_START )) {
507
- result = - EBUSY ;
508
- goto unlock ;
509
- }
510
- timeri -> ticks = timeri -> cticks = ticks ;
511
- timeri -> pticks = 0 ;
512
- result = snd_timer_start1 (timer , timeri , ticks );
513
- unlock :
514
- spin_unlock_irqrestore (& timer -> lock , flags );
515
- if (result >= 0 )
516
- snd_timer_notify1 (timeri , SNDRV_TIMER_EVENT_START );
517
- return result ;
518
- }
519
-
520
- static int _snd_timer_stop (struct snd_timer_instance * timeri , int event )
521
- {
522
- struct snd_timer * timer ;
523
- unsigned long flags ;
524
-
525
- if (snd_BUG_ON (!timeri ))
526
- return - ENXIO ;
527
-
528
- if (timeri -> flags & SNDRV_TIMER_IFLG_SLAVE ) {
529
- spin_lock_irqsave (& slave_active_lock , flags );
530
- if (!(timeri -> flags & SNDRV_TIMER_IFLG_RUNNING )) {
531
- spin_unlock_irqrestore (& slave_active_lock , flags );
532
- return - EBUSY ;
533
- }
534
- if (timeri -> timer )
535
- spin_lock (& timeri -> timer -> lock );
536
- timeri -> flags &= ~SNDRV_TIMER_IFLG_RUNNING ;
537
- list_del_init (& timeri -> ack_list );
538
- list_del_init (& timeri -> active_list );
539
- if (timeri -> timer )
540
- spin_unlock (& timeri -> timer -> lock );
541
- spin_unlock_irqrestore (& slave_active_lock , flags );
542
- goto __end ;
543
- }
544
520
timer = timeri -> timer ;
545
521
if (!timer )
546
522
return - EINVAL ;
547
523
spin_lock_irqsave (& timer -> lock , flags );
548
524
if (!(timeri -> flags & (SNDRV_TIMER_IFLG_RUNNING |
549
525
SNDRV_TIMER_IFLG_START ))) {
550
- spin_unlock_irqrestore ( & timer -> lock , flags ) ;
551
- return - EBUSY ;
526
+ result = - EBUSY ;
527
+ goto unlock ;
552
528
}
553
529
list_del_init (& timeri -> ack_list );
554
530
list_del_init (& timeri -> active_list );
555
- if (timer -> card && timer -> card -> shutdown ) {
556
- spin_unlock_irqrestore (& timer -> lock , flags );
557
- return 0 ;
531
+ if (timer -> card && timer -> card -> shutdown )
532
+ goto unlock ;
533
+ if (stop ) {
534
+ timeri -> cticks = timeri -> ticks ;
535
+ timeri -> pticks = 0 ;
558
536
}
559
537
if ((timeri -> flags & SNDRV_TIMER_IFLG_RUNNING ) &&
560
538
!(-- timer -> running )) {
@@ -569,76 +547,82 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
569
547
}
570
548
}
571
549
timeri -> flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START );
550
+ snd_timer_notify1 (timeri , stop ? SNDRV_TIMER_EVENT_STOP :
551
+ SNDRV_TIMER_EVENT_CONTINUE );
552
+ unlock :
572
553
spin_unlock_irqrestore (& timer -> lock , flags );
573
- __end :
574
- if (event != SNDRV_TIMER_EVENT_RESOLUTION )
575
- snd_timer_notify1 (timeri , event );
554
+ return result ;
555
+ }
556
+
557
+ /* stop/pause a slave timer */
558
+ static int snd_timer_stop_slave (struct snd_timer_instance * timeri , bool stop )
559
+ {
560
+ unsigned long flags ;
561
+
562
+ spin_lock_irqsave (& slave_active_lock , flags );
563
+ if (!(timeri -> flags & SNDRV_TIMER_IFLG_RUNNING )) {
564
+ spin_unlock_irqrestore (& slave_active_lock , flags );
565
+ return - EBUSY ;
566
+ }
567
+ timeri -> flags &= ~SNDRV_TIMER_IFLG_RUNNING ;
568
+ if (timeri -> timer ) {
569
+ spin_lock (& timeri -> timer -> lock );
570
+ list_del_init (& timeri -> ack_list );
571
+ list_del_init (& timeri -> active_list );
572
+ snd_timer_notify1 (timeri , stop ? SNDRV_TIMER_EVENT_STOP :
573
+ SNDRV_TIMER_EVENT_CONTINUE );
574
+ spin_unlock (& timeri -> timer -> lock );
575
+ }
576
+ spin_unlock_irqrestore (& slave_active_lock , flags );
576
577
return 0 ;
577
578
}
578
579
580
+ /*
581
+ * start the timer instance
582
+ */
583
+ int snd_timer_start (struct snd_timer_instance * timeri , unsigned int ticks )
584
+ {
585
+ if (timeri == NULL || ticks < 1 )
586
+ return - EINVAL ;
587
+ if (timeri -> flags & SNDRV_TIMER_IFLG_SLAVE )
588
+ return snd_timer_start_slave (timeri , true);
589
+ else
590
+ return snd_timer_start1 (timeri , true, ticks );
591
+ }
592
+
579
593
/*
580
594
* stop the timer instance.
581
595
*
582
596
* do not call this from the timer callback!
583
597
*/
584
598
int snd_timer_stop (struct snd_timer_instance * timeri )
585
599
{
586
- struct snd_timer * timer ;
587
- unsigned long flags ;
588
- int err ;
589
-
590
- err = _snd_timer_stop (timeri , SNDRV_TIMER_EVENT_STOP );
591
- if (err < 0 )
592
- return err ;
593
- timer = timeri -> timer ;
594
- if (!timer )
595
- return - EINVAL ;
596
- spin_lock_irqsave (& timer -> lock , flags );
597
- timeri -> cticks = timeri -> ticks ;
598
- timeri -> pticks = 0 ;
599
- spin_unlock_irqrestore (& timer -> lock , flags );
600
- return 0 ;
600
+ if (timeri -> flags & SNDRV_TIMER_IFLG_SLAVE )
601
+ return snd_timer_stop_slave (timeri , true);
602
+ else
603
+ return snd_timer_stop1 (timeri , true);
601
604
}
602
605
603
606
/*
604
607
* start again.. the tick is kept.
605
608
*/
606
609
int snd_timer_continue (struct snd_timer_instance * timeri )
607
610
{
608
- struct snd_timer * timer ;
609
- int result = - EINVAL ;
610
- unsigned long flags ;
611
-
612
- if (timeri == NULL )
613
- return result ;
614
611
if (timeri -> flags & SNDRV_TIMER_IFLG_SLAVE )
615
- return snd_timer_start_slave (timeri );
616
- timer = timeri -> timer ;
617
- if (! timer )
618
- return - EINVAL ;
619
- if (timer -> card && timer -> card -> shutdown )
620
- return - ENODEV ;
621
- spin_lock_irqsave (& timer -> lock , flags );
622
- if (timeri -> flags & SNDRV_TIMER_IFLG_RUNNING ) {
623
- result = - EBUSY ;
624
- goto unlock ;
625
- }
626
- if (!timeri -> cticks )
627
- timeri -> cticks = 1 ;
628
- timeri -> pticks = 0 ;
629
- result = snd_timer_start1 (timer , timeri , timer -> sticks );
630
- unlock :
631
- spin_unlock_irqrestore (& timer -> lock , flags );
632
- snd_timer_notify1 (timeri , SNDRV_TIMER_EVENT_CONTINUE );
633
- return result ;
612
+ return snd_timer_start_slave (timeri , false);
613
+ else
614
+ return snd_timer_start1 (timeri , false, 0 );
634
615
}
635
616
636
617
/*
637
618
* pause.. remember the ticks left
638
619
*/
639
620
int snd_timer_pause (struct snd_timer_instance * timeri )
640
621
{
641
- return _snd_timer_stop (timeri , SNDRV_TIMER_EVENT_PAUSE );
622
+ if (timeri -> flags & SNDRV_TIMER_IFLG_SLAVE )
623
+ return snd_timer_stop_slave (timeri , false);
624
+ else
625
+ return snd_timer_stop1 (timeri , false);
642
626
}
643
627
644
628
/*
0 commit comments