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: hdsp: Replace tasklet with work

The tasklet is an old API that should be deprecated, usually can be
converted to another decent API. In HDSP driver, a tasklet is still
used for offloading the MIDI I/O handling (optional via mixer
switch). It can be achieved gracefully with a work queued, too.

This patch replaces the tasklet usage in HDSP driver with a simple
work. The conversion is fairly straightforward. The only significant
difference is that a superfluous tasklet_kill() call is removed from
snd_hdap_midi_input_trigger().

Link: https://lore.kernel.org/r/20200903104131.21097-7-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+27 -28
+27 -28
sound/pci/rme9652/hdsp.c
··· 447 447 struct snd_pcm_substream *capture_substream; 448 448 struct snd_pcm_substream *playback_substream; 449 449 struct hdsp_midi midi[2]; 450 - struct tasklet_struct midi_tasklet; 451 - int use_midi_tasklet; 450 + struct work_struct midi_work; 451 + int use_midi_work; 452 452 int precise_ptr; 453 453 u32 control_register; /* cached value */ 454 454 u32 control2_register; /* cached value */ ··· 1385 1385 } 1386 1386 } else { 1387 1387 hdsp->control_register &= ~ie; 1388 - tasklet_kill(&hdsp->midi_tasklet); 1389 1388 } 1390 1389 1391 1390 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); ··· 2541 2542 return change; 2542 2543 } 2543 2544 2544 - #define HDSP_USE_MIDI_TASKLET(xname, xindex) \ 2545 + #define HDSP_USE_MIDI_WORK(xname, xindex) \ 2545 2546 { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ 2546 2547 .name = xname, \ 2547 2548 .index = xindex, \ 2548 - .info = snd_hdsp_info_use_midi_tasklet, \ 2549 - .get = snd_hdsp_get_use_midi_tasklet, \ 2550 - .put = snd_hdsp_put_use_midi_tasklet \ 2549 + .info = snd_hdsp_info_use_midi_work, \ 2550 + .get = snd_hdsp_get_use_midi_work, \ 2551 + .put = snd_hdsp_put_use_midi_work \ 2551 2552 } 2552 2553 2553 - static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet) 2554 + static int hdsp_set_use_midi_work(struct hdsp *hdsp, int use_work) 2554 2555 { 2555 - if (use_tasklet) 2556 - hdsp->use_midi_tasklet = 1; 2556 + if (use_work) 2557 + hdsp->use_midi_work = 1; 2557 2558 else 2558 - hdsp->use_midi_tasklet = 0; 2559 + hdsp->use_midi_work = 0; 2559 2560 return 0; 2560 2561 } 2561 2562 2562 - #define snd_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info 2563 + #define snd_hdsp_info_use_midi_work snd_ctl_boolean_mono_info 2563 2564 2564 - static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2565 + static int snd_hdsp_get_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2565 2566 { 2566 2567 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 2567 2568 2568 2569 spin_lock_irq(&hdsp->lock); 2569 - ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet; 2570 + ucontrol->value.integer.value[0] = hdsp->use_midi_work; 2570 2571 spin_unlock_irq(&hdsp->lock); 2571 2572 return 0; 2572 2573 } 2573 2574 2574 - static int snd_hdsp_put_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2575 + static int snd_hdsp_put_use_midi_work(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 2575 2576 { 2576 2577 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 2577 2578 int change; ··· 2581 2582 return -EBUSY; 2582 2583 val = ucontrol->value.integer.value[0] & 1; 2583 2584 spin_lock_irq(&hdsp->lock); 2584 - change = (int)val != hdsp->use_midi_tasklet; 2585 - hdsp_set_use_midi_tasklet(hdsp, val); 2585 + change = (int)val != hdsp->use_midi_work; 2586 + hdsp_set_use_midi_work(hdsp, val); 2586 2587 spin_unlock_irq(&hdsp->lock); 2587 2588 return change; 2588 2589 } ··· 2949 2950 HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), 2950 2951 HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut), 2951 2952 HDSP_PRECISE_POINTER("Precise Pointer", 0), 2952 - HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), 2953 + HDSP_USE_MIDI_WORK("Use Midi Tasklet", 0), 2953 2954 }; 2954 2955 2955 2956 ··· 3369 3370 snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0)); 3370 3371 snd_iprintf(buffer, "MIDI2 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut1)); 3371 3372 snd_iprintf(buffer, "MIDI2 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn1)); 3372 - snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_tasklet ? "on" : "off"); 3373 + snd_iprintf(buffer, "Use Midi Tasklet: %s\n", hdsp->use_midi_work ? "on" : "off"); 3373 3374 3374 3375 snd_iprintf(buffer, "\n"); 3375 3376 ··· 3790 3791 return 0; 3791 3792 } 3792 3793 3793 - static void hdsp_midi_tasklet(struct tasklet_struct *t) 3794 + static void hdsp_midi_work(struct work_struct *work) 3794 3795 { 3795 - struct hdsp *hdsp = from_tasklet(hdsp, t, midi_tasklet); 3796 + struct hdsp *hdsp = container_of(work, struct hdsp, midi_work); 3796 3797 3797 3798 if (hdsp->midi[0].pending) 3798 3799 snd_hdsp_midi_input_read (&hdsp->midi[0]); ··· 3837 3838 } 3838 3839 3839 3840 if (midi0 && midi0status) { 3840 - if (hdsp->use_midi_tasklet) { 3841 + if (hdsp->use_midi_work) { 3841 3842 /* we disable interrupts for this input until processing is done */ 3842 3843 hdsp->control_register &= ~HDSP_Midi0InterruptEnable; 3843 3844 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); ··· 3848 3849 } 3849 3850 } 3850 3851 if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) { 3851 - if (hdsp->use_midi_tasklet) { 3852 + if (hdsp->use_midi_work) { 3852 3853 /* we disable interrupts for this input until processing is done */ 3853 3854 hdsp->control_register &= ~HDSP_Midi1InterruptEnable; 3854 3855 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); ··· 3858 3859 snd_hdsp_midi_input_read (&hdsp->midi[1]); 3859 3860 } 3860 3861 } 3861 - if (hdsp->use_midi_tasklet && schedule) 3862 - tasklet_schedule(&hdsp->midi_tasklet); 3862 + if (hdsp->use_midi_work && schedule) 3863 + queue_work(system_highpri_wq, &hdsp->midi_work); 3863 3864 return IRQ_HANDLED; 3864 3865 } 3865 3866 ··· 5181 5182 5182 5183 spin_lock_init(&hdsp->lock); 5183 5184 5184 - tasklet_setup(&hdsp->midi_tasklet, hdsp_midi_tasklet); 5185 + INIT_WORK(&hdsp->midi_work, hdsp_midi_work); 5185 5186 5186 5187 pci_read_config_word(hdsp->pci, PCI_CLASS_REVISION, &hdsp->firmware_rev); 5187 5188 hdsp->firmware_rev &= 0xff; ··· 5234 5235 hdsp->irq = pci->irq; 5235 5236 card->sync_irq = hdsp->irq; 5236 5237 hdsp->precise_ptr = 0; 5237 - hdsp->use_midi_tasklet = 1; 5238 + hdsp->use_midi_work = 1; 5238 5239 hdsp->dds_value = 0; 5239 5240 5240 5241 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) ··· 5304 5305 { 5305 5306 if (hdsp->port) { 5306 5307 /* stop the audio, and cancel all interrupts */ 5307 - tasklet_kill(&hdsp->midi_tasklet); 5308 + cancel_work_sync(&hdsp->midi_work); 5308 5309 hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable); 5309 5310 hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register); 5310 5311 }