// The program in user process should periodically check the status of intermediate
                // buffer associated to PCM substream to process PCM frames in the buffer, instead
                // of receiving notification of period elapsed by poll wait.
-               if (!pcm->runtime->no_period_wakeup)
-                       queue_work(system_highpri_wq, &s->period_work);
+               if (!pcm->runtime->no_period_wakeup) {
+                       if (in_interrupt()) {
+                               // In software IRQ context for 1394 OHCI.
+                               snd_pcm_period_elapsed(pcm);
+                       } else {
+                               // In process context of ALSA PCM application under acquired lock of
+                               // PCM substream.
+                               snd_pcm_period_elapsed_under_stream_lock(pcm);
+                       }
+               }
        }
 }
 
 {
        struct amdtp_stream *irq_target = d->irq_target;
 
+       // Process isochronous packets queued till recent isochronous cycle to handle PCM frames.
        if (irq_target && amdtp_stream_running(irq_target)) {
-               // This function is called in software IRQ context of
-               // period_work or process context.
-               //
-               // When the software IRQ context was scheduled by software IRQ
-               // context of IT contexts, queued packets were already handled.
-               // Therefore, no need to flush the queue in buffer furthermore.
-               //
-               // When the process context reach here, some packets will be
-               // already queued in the buffer. These packets should be handled
-               // immediately to keep better granularity of PCM pointer.
-               //
-               // Later, the process context will sometimes schedules software
-               // IRQ context of the period_work. Then, no need to flush the
-               // queue by the same reason as described in the above
-               if (current_work() != &s->period_work)
+               // In software IRQ context, the call causes dead-lock to disable the tasklet
+               // synchronously.
+               if (!in_interrupt())
                        fw_iso_context_flush_completions(irq_target->context);
        }