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: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
2ac55daffe
commit
ce4f257593
|
@ -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,25 +912,15 @@ 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)
|
||||
{
|
||||
struct snd_card_asihpi *asihpi = from_tasklet(asihpi, t, t);
|
||||
struct hpi_adapter *a = asihpi->hpi;
|
||||
|
||||
WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
|
||||
asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
|
||||
if (asihpi->llmode_streampriv)
|
||||
snd_card_asihpi_timer_function(
|
||||
&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);
|
||||
if (asihpi->llmode_streampriv)
|
||||
snd_card_asihpi_timer_function(
|
||||
&asihpi->llmode_streampriv->timer);
|
||||
}
|
||||
|
||||
/***************************** PLAYBACK OPS ****************/
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue