summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function/f_midi.c
diff options
context:
space:
mode:
authorDavidlohr Bueso <dave@stgolabs.net>2021-01-10 20:28:55 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-01-12 12:52:28 +0100
commit8653d71ce3763aedcf3d2331f59beda3fecd79e4 (patch)
treec7b041caeb00e3466c430d4280247148cc8b3812 /drivers/usb/gadget/function/f_midi.c
parent0c0a20f6da04780b94e3ccc43101dde6f536ab37 (diff)
usb/gadget: f_midi: Replace tasklet with work
Currently a tasklet is used to transmit input substream buffer data. However, tasklets have long been deprecated as being too heavy on the system by running in irq context - and this is not a performance critical path. If a higher priority process wants to run, it must wait for the tasklet to finish before doing so. Deferring work to a workqueue and executing in process context should be fine considering the callback already does f_midi_do_transmit() under the transmit_lock and thus changes in semantics are ok regarding concurrency - tasklets being serialized against itself. Cc: Takashi Iwai <tiwai@suse.de> Reviewed-by: Takashi Iwai <tiwai@suse.de> Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Davidlohr Bueso <dbueso@suse.de> Link: https://lore.kernel.org/r/20210111042855.73289-1-dave@stgolabs.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget/function/f_midi.c')
-rw-r--r--drivers/usb/gadget/function/f_midi.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index 8fff995b8dd5..71a1a26e85c7 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -87,7 +87,7 @@ struct f_midi {
struct snd_rawmidi_substream *out_substream[MAX_PORTS];
unsigned long out_triggered;
- struct tasklet_struct tasklet;
+ struct work_struct work;
unsigned int in_ports;
unsigned int out_ports;
int index;
@@ -698,9 +698,11 @@ drop_out:
f_midi_drop_out_substreams(midi);
}
-static void f_midi_in_tasklet(struct tasklet_struct *t)
+static void f_midi_in_work(struct work_struct *work)
{
- struct f_midi *midi = from_tasklet(midi, t, tasklet);
+ struct f_midi *midi;
+
+ midi = container_of(work, struct f_midi, work);
f_midi_transmit(midi);
}
@@ -737,7 +739,7 @@ static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up)
VDBG(midi, "%s() %d\n", __func__, up);
midi->in_ports_array[substream->number].active = up;
if (up)
- tasklet_hi_schedule(&midi->tasklet);
+ queue_work(system_highpri_wq, &midi->work);
}
static int f_midi_out_open(struct snd_rawmidi_substream *substream)
@@ -875,7 +877,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0;
midi->gadget = cdev->gadget;
- tasklet_setup(&midi->tasklet, f_midi_in_tasklet);
+ INIT_WORK(&midi->work, f_midi_in_work);
status = f_midi_register_card(midi);
if (status < 0)
goto fail_register;