ALSA: usb-audio: Replace tasklet with work

The tasklet is an old API that should be deprecated, usually can be
converted to another decent API.  In USB-audio driver, a tasklet is
still used in MIDI interface code for handling the output byte
stream.  It can be achieved gracefully with a work queued in the
high-prio system workqueue.

This patch replaces the tasklet usage in USB-audio driver with a
simple work.

Link: https://lore.kernel.org/r/20200903104131.21097-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2020-09-03 12:41:23 +02:00
parent bf0835957f
commit c7d9efdff6

View File

@ -142,7 +142,7 @@ struct snd_usb_midi_out_endpoint {
unsigned int active_urbs;
unsigned int drain_urbs;
int max_transfer; /* size of urb buffer */
struct tasklet_struct tasklet;
struct work_struct work;
unsigned int next_urb;
spinlock_t buffer_lock;
@ -344,9 +344,10 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
spin_unlock_irqrestore(&ep->buffer_lock, flags);
}
static void snd_usbmidi_out_tasklet(struct tasklet_struct *t)
static void snd_usbmidi_out_work(struct work_struct *work)
{
struct snd_usb_midi_out_endpoint *ep = from_tasklet(ep, t, tasklet);
struct snd_usb_midi_out_endpoint *ep =
container_of(work, struct snd_usb_midi_out_endpoint, work);
snd_usbmidi_do_output(ep);
}
@ -1177,7 +1178,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
snd_rawmidi_proceed(substream);
return;
}
tasklet_schedule(&port->ep->tasklet);
queue_work(system_highpri_wq, &port->ep->work);
}
}
@ -1440,7 +1441,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi,
}
spin_lock_init(&ep->buffer_lock);
tasklet_setup(&ep->tasklet, snd_usbmidi_out_tasklet);
INIT_WORK(&ep->work, snd_usbmidi_out_work);
init_waitqueue_head(&ep->drain_wait);
for (i = 0; i < 0x10; ++i)
@ -1503,7 +1504,7 @@ void snd_usbmidi_disconnect(struct list_head *p)
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
if (ep->out)
tasklet_kill(&ep->out->tasklet);
cancel_work_sync(&ep->out->work);
if (ep->out) {
for (j = 0; j < OUTPUT_URBS; ++j)
usb_kill_urb(ep->out->urbs[j].urb);