[PATCH 09/11] ALSA: asihpi: Replace tasklet with threaded irq
Takashi Iwai
tiwai at suse.de
Thu Sep 3 12:41:29 CEST 2020
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.
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
sound/pci/asihpi/asihpi.c | 28 +++-------------------------
sound/pci/asihpi/hpioctl.c | 16 +++++++++++++---
2 files changed, 16 insertions(+), 28 deletions(-)
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 35e76480306e..46d8166ceaeb 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -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 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev,
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);
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 496dcde9715d..6cc2b6964bb5 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -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;
--
2.16.4
More information about the Alsa-devel
mailing list