Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+17 -29
+4 -26
sound/pci/asihpi/asihpi.c
··· 117 117 * snd_card_asihpi_timer_function(). 118 118 */ 119 119 struct snd_card_asihpi_pcm *llmode_streampriv; 120 - struct tasklet_struct t; 121 120 void (*pcm_start)(struct snd_pcm_substream *substream); 122 121 void (*pcm_stop)(struct snd_pcm_substream *substream); 123 122 ··· 546 547 card = snd_pcm_substream_chip(substream); 547 548 548 549 WARN_ON(in_interrupt()); 549 - tasklet_disable(&card->t); 550 550 card->llmode_streampriv = dpcm; 551 - tasklet_enable(&card->t); 552 551 553 552 hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, 554 553 HPI_ADAPTER_PROPERTY_IRQ_RATE, ··· 562 565 hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, 563 566 HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); 564 567 565 - if (in_interrupt()) 566 - card->llmode_streampriv = NULL; 567 - else { 568 - tasklet_disable(&card->t); 569 - card->llmode_streampriv = NULL; 570 - tasklet_enable(&card->t); 571 - } 568 + card->llmode_streampriv = NULL; 572 569 } 573 570 574 571 static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, ··· 912 921 add_timer(&dpcm->timer); 913 922 } 914 923 915 - static void snd_card_asihpi_int_task(struct tasklet_struct *t) 916 - { 917 - struct snd_card_asihpi *asihpi = from_tasklet(asihpi, t, t); 918 - struct hpi_adapter *a = asihpi->hpi; 919 - 920 - WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); 921 - asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; 922 - if (asihpi->llmode_streampriv) 923 - snd_card_asihpi_timer_function( 924 - &asihpi->llmode_streampriv->timer); 925 - } 926 - 927 924 static void snd_card_asihpi_isr(struct hpi_adapter *a) 928 925 { 929 926 struct snd_card_asihpi *asihpi; 930 927 931 928 WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); 932 929 asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; 933 - tasklet_schedule(&asihpi->t); 930 + if (asihpi->llmode_streampriv) 931 + snd_card_asihpi_timer_function( 932 + &asihpi->llmode_streampriv->timer); 934 933 } 935 934 936 935 /***************************** PLAYBACK OPS ****************/ ··· 2852 2871 if (hpi->interrupt_mode) { 2853 2872 asihpi->pcm_start = snd_card_asihpi_pcm_int_start; 2854 2873 asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop; 2855 - tasklet_setup(&asihpi->t, snd_card_asihpi_int_task); 2856 2874 hpi->interrupt_callback = snd_card_asihpi_isr; 2857 2875 } else { 2858 2876 asihpi->pcm_start = snd_card_asihpi_pcm_timer_start; ··· 2940 2960 static void snd_asihpi_remove(struct pci_dev *pci_dev) 2941 2961 { 2942 2962 struct hpi_adapter *hpi = pci_get_drvdata(pci_dev); 2943 - struct snd_card_asihpi *asihpi = hpi->snd_card->private_data; 2944 2963 2945 2964 /* Stop interrupts */ 2946 2965 if (hpi->interrupt_mode) { 2947 2966 hpi->interrupt_callback = NULL; 2948 2967 hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index, 2949 2968 HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); 2950 - tasklet_kill(&asihpi->t); 2951 2969 } 2952 2970 2953 2971 snd_card_free(hpi->snd_card);
+13 -3
sound/pci/asihpi/hpioctl.c
··· 329 329 asihpi_irq_count, a->adapter->type, a->adapter->index); */ 330 330 331 331 if (a->interrupt_callback) 332 - a->interrupt_callback(a); 332 + return IRQ_WAKE_THREAD; 333 333 334 + return IRQ_HANDLED; 335 + } 336 + 337 + static irqreturn_t asihpi_isr_thread(int irq, void *dev_id) 338 + { 339 + struct hpi_adapter *a = dev_id; 340 + 341 + if (a->interrupt_callback) 342 + a->interrupt_callback(a); 334 343 return IRQ_HANDLED; 335 344 } 336 345 ··· 487 478 } 488 479 489 480 /* Note: request_irq calls asihpi_isr here */ 490 - if (request_irq(pci_dev->irq, asihpi_isr, IRQF_SHARED, 491 - "asihpi", &adapters[adapter_index])) { 481 + if (request_threaded_irq(pci_dev->irq, asihpi_isr, 482 + asihpi_isr_thread, IRQF_SHARED, 483 + "asihpi", &adapters[adapter_index])) { 492 484 dev_err(&pci_dev->dev, "request_irq(%d) failed\n", 493 485 pci_dev->irq); 494 486 goto err;