ALSA: korg1212: Replace the pending stop check code with sync_stop PCM ops
authorTakashi Iwai <tiwai@suse.de>
Tue, 15 Apr 2025 15:55:21 +0000 (17:55 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 29 Apr 2025 12:53:54 +0000 (14:53 +0200)
The korg1212 driver has an overly complex code with the timer API to
check the pending stop operation and to sync at the prepare stage.
This very same thing can be achieved more simply by the PCM sync_stop
ops without timer, and this patch implements it.

Along with the rewrite to sync_stop ops, the flag
dsp_stop_is_processed is replaced with dsp_stop_processing to indicate
the stop operation is pending, not to indicate it's finished.  In that
way, wait_for_event() can be used more straightforwardly.

Link: https://lore.kernel.org/590769506CF46967+20250414042629.63019-5-wangyuli@uniontech.com
Link: https://patch.msgid.link/20250415155522.7998-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/korg1212/korg1212.c

index 49b71082c48597e93cb2062ac699deb71d639143..56dea5b10828a90f9e6f5b95249bb50f23c599a8 100644 (file)
@@ -308,9 +308,6 @@ struct snd_korg1212 {
         spinlock_t    lock;
        struct mutex open_mutex;
 
-       struct timer_list timer;        /* timer callback for checking ack of stop request */
-       int stop_pending_cnt;           /* counter for stop pending check */
-
         wait_queue_head_t wait;
 
         unsigned long iomem;
@@ -382,7 +379,7 @@ struct snd_korg1212 {
        unsigned long totalerrorcnt; // Total Error Count
 
        int dsp_is_loaded;
-       int dsp_stop_is_processed;
+       int dsp_stop_processing;
 
 };
 
@@ -565,52 +562,17 @@ static int snd_korg1212_Send1212Command(struct snd_korg1212 *korg1212,
 /* spinlock already held */
 static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212)
 {
-       if (! korg1212->stop_pending_cnt) {
-               korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
-               /* program the timer */
-               korg1212->stop_pending_cnt = HZ;
-               mod_timer(&korg1212->timer, jiffies + 1);
-       }
+       korg1212->dsp_stop_processing = 1;
+       korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
 }
 
 static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
 {
        unsigned long flags;
        spin_lock_irqsave(&korg1212->lock, flags);
-       korg1212->dsp_stop_is_processed = 0;
        snd_korg1212_SendStop(korg1212);
        spin_unlock_irqrestore(&korg1212->lock, flags);
-       wait_event_timeout(korg1212->wait, korg1212->dsp_stop_is_processed, (HZ * 3) / 2);
-}
-
-/* timer callback for checking the ack of stop request */
-static void snd_korg1212_timer_func(struct timer_list *t)
-{
-       struct snd_korg1212 *korg1212 = from_timer(korg1212, t, timer);
-       unsigned long flags;
-       
-       spin_lock_irqsave(&korg1212->lock, flags);
-       if (korg1212->sharedBufferPtr->cardCommand == 0) {
-               /* ack'ed */
-               korg1212->stop_pending_cnt = 0;
-               korg1212->dsp_stop_is_processed = 1;
-               wake_up(&korg1212->wait);
-               K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Stop ack'ed [%s]\n",
-                                          stateName[korg1212->cardState]);
-       } else {
-               if (--korg1212->stop_pending_cnt > 0) {
-                       /* reprogram timer */
-                       mod_timer(&korg1212->timer, jiffies + 1);
-               } else {
-                       dev_dbg(korg1212->card->dev, "korg1212_timer_func timeout\n");
-                       korg1212->sharedBufferPtr->cardCommand = 0;
-                       korg1212->dsp_stop_is_processed = 1;
-                       wake_up(&korg1212->wait);
-                       K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n",
-                                          stateName[korg1212->cardState]);
-               }
-       }
-       spin_unlock_irqrestore(&korg1212->lock, flags);
+       wait_event_timeout(korg1212->wait, !korg1212->dsp_stop_processing, HZ);
 }
 
 static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
@@ -1135,7 +1097,9 @@ static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
                        korg1212->errorcnt++;
                        korg1212->totalerrorcnt++;
                        korg1212->sharedBufferPtr->cardCommand = 0;
+                       korg1212->dsp_stop_processing = 0;
                        snd_korg1212_setCardState(korg1212, K1212_STATE_ERRORSTOP);
+                       wake_up(&korg1212->wait);
                         break;
 
                 // ------------------------------------------------------------------------
@@ -1147,6 +1111,8 @@ static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
                                                   korg1212->irqcount, doorbellValue,
                                                   stateName[korg1212->cardState]);
                        korg1212->sharedBufferPtr->cardCommand = 0;
+                       korg1212->dsp_stop_processing = 0;
+                       wake_up(&korg1212->wait);
                         break;
 
                 default:
@@ -1535,6 +1501,14 @@ static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
         return 0;
 }
 
+static int snd_korg1212_sync_stop(struct snd_pcm_substream *substream)
+{
+       struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
+
+       wait_event_timeout(korg1212->wait, !korg1212->dsp_stop_processing, HZ);
+       return 0;
+}
+
 static int snd_korg1212_prepare(struct snd_pcm_substream *substream)
 {
         struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
@@ -1544,19 +1518,7 @@ static int snd_korg1212_prepare(struct snd_pcm_substream *substream)
                           stateName[korg1212->cardState]);
 
        spin_lock_irq(&korg1212->lock);
-
-       /* FIXME: we should wait for ack! */
-       if (korg1212->stop_pending_cnt > 0) {
-               K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare - Stop is pending... [%s]\n",
-                                  stateName[korg1212->cardState]);
-               spin_unlock_irq(&korg1212->lock);
-               return -EAGAIN;
-               /*
-               korg1212->sharedBufferPtr->cardCommand = 0;
-               del_timer(&korg1212->timer);
-               korg1212->stop_pending_cnt = 0;
-               */
-       }
+       korg1212->dsp_stop_processing = 0;
 
         rc = snd_korg1212_SetupForPlay(korg1212);
 
@@ -1668,6 +1630,7 @@ static const struct snd_pcm_ops snd_korg1212_playback_ops = {
         .hw_params =   snd_korg1212_hw_params,
         .prepare =     snd_korg1212_prepare,
         .trigger =     snd_korg1212_trigger,
+       .sync_stop =    snd_korg1212_sync_stop,
         .pointer =     snd_korg1212_playback_pointer,
        .copy =         snd_korg1212_playback_copy,
        .fill_silence = snd_korg1212_playback_silence,
@@ -1680,6 +1643,7 @@ static const struct snd_pcm_ops snd_korg1212_capture_ops = {
        .hw_params =    snd_korg1212_hw_params,
        .prepare =      snd_korg1212_prepare,
        .trigger =      snd_korg1212_trigger,
+       .sync_stop =    snd_korg1212_sync_stop,
        .pointer =      snd_korg1212_capture_pointer,
        .copy =         snd_korg1212_capture_copy,
 };
@@ -2086,7 +2050,6 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci)
         init_waitqueue_head(&korg1212->wait);
         spin_lock_init(&korg1212->lock);
        mutex_init(&korg1212->open_mutex);
-       timer_setup(&korg1212->timer, snd_korg1212_timer_func, 0);
 
         korg1212->irq = -1;
         korg1212->clkSource = K1212_CLKIDX_Local;