Commit ce4f2575 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: asihpi: Replace tasklet with threaded irq

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 2ac55daf
Loading
Loading
Loading
Loading
+3 −25
Original line number Diff line number Diff line
@@ -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);
	}
}

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);
+13 −3
Original line number Diff line number Diff line
@@ -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,7 +487,8 @@ 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,
		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);