ALSA: asihpi: Replace tasklet with threaded irq
authorTakashi Iwai <tiwai@suse.de>
Thu, 3 Sep 2020 10:41:29 +0000 (12:41 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 9 Sep 2020 16:34:20 +0000 (18:34 +0200)
The tasklet is an old API that should be deprecated, usually can be
converted to another decent API.  In ASIHPI driver, a tasklet is
still used for offloading the PCM IRQ handling.  It can be achieved
gracefully with a threaded IRQ, too.

This patch replaces the tasklet usage in asihpi driver with a threaded
IRQ.  It also simplified some call patterns.

Link: https://lore.kernel.org/r/20200903104131.21097-10-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/asihpi/asihpi.c
sound/pci/asihpi/hpioctl.c

index 35e7648..46d8166 100644 (file)
@@ -117,7 +117,6 @@ struct snd_card_asihpi {
         * snd_card_asihpi_timer_function().
         */
        struct snd_card_asihpi_pcm *llmode_streampriv;
-       struct tasklet_struct t;
        void (*pcm_start)(struct snd_pcm_substream *substream);
        void (*pcm_stop)(struct snd_pcm_substream *substream);
 
@@ -547,9 +546,7 @@ static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
        card = snd_pcm_substream_chip(substream);
 
        WARN_ON(in_interrupt());
-       tasklet_disable(&card->t);
        card->llmode_streampriv = dpcm;
-       tasklet_enable(&card->t);
 
        hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
                HPI_ADAPTER_PROPERTY_IRQ_RATE,
@@ -565,13 +562,7 @@ static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
        hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
                HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
 
-       if (in_interrupt())
-               card->llmode_streampriv = NULL;
-       else {
-               tasklet_disable(&card->t);
-               card->llmode_streampriv = NULL;
-               tasklet_enable(&card->t);
-       }
+       card->llmode_streampriv = NULL;
 }
 
 static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
@@ -921,10 +912,9 @@ static void snd_card_asihpi_timer_function(struct timer_list *t)
                add_timer(&dpcm->timer);
 }
 
-static void snd_card_asihpi_int_task(struct tasklet_struct *t)
+static void snd_card_asihpi_isr(struct hpi_adapter *a)
 {
-       struct snd_card_asihpi *asihpi = from_tasklet(asihpi, t, t);
-       struct hpi_adapter *a = asihpi->hpi;
+       struct snd_card_asihpi *asihpi;
 
        WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
        asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
@@ -933,15 +923,6 @@ static void snd_card_asihpi_int_task(struct tasklet_struct *t)
                        &asihpi->llmode_streampriv->timer);
 }
 
-static void snd_card_asihpi_isr(struct hpi_adapter *a)
-{
-       struct snd_card_asihpi *asihpi;
-
-       WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
-       asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
-       tasklet_schedule(&asihpi->t);
-}
-
 /***************************** PLAYBACK OPS ****************/
 static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
                                            substream)
@@ -2871,7 +2852,6 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev,
        if (hpi->interrupt_mode) {
                asihpi->pcm_start = snd_card_asihpi_pcm_int_start;
                asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop;
-               tasklet_setup(&asihpi->t, snd_card_asihpi_int_task);
                hpi->interrupt_callback = snd_card_asihpi_isr;
        } else {
                asihpi->pcm_start = snd_card_asihpi_pcm_timer_start;
@@ -2960,14 +2940,12 @@ __nodev:
 static void snd_asihpi_remove(struct pci_dev *pci_dev)
 {
        struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
-       struct snd_card_asihpi *asihpi = hpi->snd_card->private_data;
 
        /* Stop interrupts */
        if (hpi->interrupt_mode) {
                hpi->interrupt_callback = NULL;
                hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index,
                        HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
-               tasklet_kill(&asihpi->t);
        }
 
        snd_card_free(hpi->snd_card);
index 496dcde..6cc2b69 100644 (file)
@@ -329,11 +329,20 @@ static irqreturn_t asihpi_isr(int irq, void *dev_id)
           asihpi_irq_count, a->adapter->type, a->adapter->index); */
 
        if (a->interrupt_callback)
-               a->interrupt_callback(a);
+               return IRQ_WAKE_THREAD;
 
        return IRQ_HANDLED;
 }
 
+static irqreturn_t asihpi_isr_thread(int irq, void *dev_id)
+{
+       struct hpi_adapter *a = dev_id;
+
+       if (a->interrupt_callback)
+               a->interrupt_callback(a);
+       return IRQ_HANDLED;
+}
+
 int asihpi_adapter_probe(struct pci_dev *pci_dev,
                         const struct pci_device_id *pci_id)
 {
@@ -478,8 +487,9 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev,
                }
 
                /* Note: request_irq calls asihpi_isr here */
-               if (request_irq(pci_dev->irq, asihpi_isr, IRQF_SHARED,
-                               "asihpi", &adapters[adapter_index])) {
+               if (request_threaded_irq(pci_dev->irq, asihpi_isr,
+                                        asihpi_isr_thread, IRQF_SHARED,
+                                        "asihpi", &adapters[adapter_index])) {
                        dev_err(&pci_dev->dev, "request_irq(%d) failed\n",
                                pci_dev->irq);
                        goto err;