|
77 | 77 | // overrun. Actual device can skip more, then this module stops the packet streaming.
|
78 | 78 | #define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES 5
|
79 | 79 |
|
| 80 | +static void pcm_period_work(struct work_struct *work); |
| 81 | + |
80 | 82 | /**
|
81 | 83 | * amdtp_stream_init - initialize an AMDTP stream structure
|
82 | 84 | * @s: the AMDTP stream to initialize
|
@@ -105,6 +107,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
|
105 | 107 | s->flags = flags;
|
106 | 108 | s->context = ERR_PTR(-1);
|
107 | 109 | mutex_init(&s->mutex);
|
| 110 | + INIT_WORK(&s->period_work, pcm_period_work); |
108 | 111 | s->packet_index = 0;
|
109 | 112 |
|
110 | 113 | init_waitqueue_head(&s->ready_wait);
|
@@ -347,6 +350,7 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload);
|
347 | 350 | */
|
348 | 351 | void amdtp_stream_pcm_prepare(struct amdtp_stream *s)
|
349 | 352 | {
|
| 353 | + cancel_work_sync(&s->period_work); |
350 | 354 | s->pcm_buffer_pointer = 0;
|
351 | 355 | s->pcm_period_pointer = 0;
|
352 | 356 | }
|
@@ -624,6 +628,16 @@ static void update_pcm_pointers(struct amdtp_stream *s,
|
624 | 628 | }
|
625 | 629 | }
|
626 | 630 |
|
| 631 | +static void pcm_period_work(struct work_struct *work) |
| 632 | +{ |
| 633 | + struct amdtp_stream *s = container_of(work, struct amdtp_stream, |
| 634 | + period_work); |
| 635 | + struct snd_pcm_substream *pcm = READ_ONCE(s->pcm); |
| 636 | + |
| 637 | + if (pcm) |
| 638 | + snd_pcm_period_elapsed(pcm); |
| 639 | +} |
| 640 | + |
627 | 641 | static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params,
|
628 | 642 | bool sched_irq)
|
629 | 643 | {
|
@@ -1910,6 +1924,7 @@ static void amdtp_stream_stop(struct amdtp_stream *s)
|
1910 | 1924 | return;
|
1911 | 1925 | }
|
1912 | 1926 |
|
| 1927 | + cancel_work_sync(&s->period_work); |
1913 | 1928 | fw_iso_context_stop(s->context);
|
1914 | 1929 | fw_iso_context_destroy(s->context);
|
1915 | 1930 | s->context = ERR_PTR(-1);
|
|
0 commit comments