OSDN Git Service

ALSA: pcm: Add card sync_irq field
authorTakashi Iwai <tiwai@suse.de>
Sun, 17 Nov 2019 08:53:07 +0000 (09:53 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 20 Nov 2019 18:39:54 +0000 (19:39 +0100)
Many PCI and other drivers performs snd_pcm_period_elapsed() simply in
its interrupt handler, so the sync_stop operation is just to call
synchronize_irq().  Instead of putting this call multiple times,
introduce the common card->sync_irq field.  When this field is set,
PCM core performs synchronize_irq() for sync-stop operation.  Each
driver just needs to copy its local IRQ number to card->sync_irq, and
that's all we need.

Link: https://lore.kernel.org/r/20191117085308.23915-8-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/core.h
sound/core/init.c
sound/core/pcm_native.c

index ee238f1..af3dce9 100644 (file)
@@ -117,6 +117,7 @@ struct snd_card {
        struct device card_dev;         /* cardX object for sysfs */
        const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
        bool registered;                /* card_dev is registered? */
+       int sync_irq;                   /* assigned irq, used for PCM sync */
        wait_queue_head_t remove_sleep;
 
 #ifdef CONFIG_PM
index db99b7f..faa9f03 100644 (file)
@@ -215,6 +215,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
        init_waitqueue_head(&card->power_sleep);
 #endif
        init_waitqueue_head(&card->remove_sleep);
+       card->sync_irq = -1;
 
        device_initialize(&card->card_dev);
        card->card_dev.parent = parent;
index 163d621..1fe5811 100644 (file)
@@ -574,6 +574,8 @@ static void snd_pcm_sync_stop(struct snd_pcm_substream *substream)
                substream->runtime->stop_operating = false;
                if (substream->ops->sync_stop)
                        substream->ops->sync_stop(substream);
+               else if (substream->pcm->card->sync_irq > 0)
+                       synchronize_irq(substream->pcm->card->sync_irq);
        }
 }