summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-06-14 14:37:06 +0200
committerTakashi Iwai <tiwai@suse.de>2011-06-14 14:37:06 +0200
commitb3c705aa9e9147a30009bdf6ba853aa7fe138e58 (patch)
tree27e1543b2a0e441a3929b51a48bf64b77c8f06b7
parentALSA: es1968,maestro3 - Use work for hw-volume control (diff)
downloadlinux-b3c705aa9e9147a30009bdf6ba853aa7fe138e58.tar.xz
linux-b3c705aa9e9147a30009bdf6ba853aa7fe138e58.zip
ALSA: rawmidi - Use workq for event handling
Kill tasklet usage in rawmidi core code. Use workq for the event callback instead of tasklet (which is used only in core/seq/seq_midi.c). Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--include/sound/rawmidi.h4
-rw-r--r--sound/core/rawmidi.c37
2 files changed, 14 insertions, 27 deletions
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 2480e7d10dcf..6b14359d9fed 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -27,6 +27,7 @@
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/mutex.h>
+#include <linux/workqueue.h>
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
#include "seq_device.h"
@@ -63,6 +64,7 @@ struct snd_rawmidi_global_ops {
};
struct snd_rawmidi_runtime {
+ struct snd_rawmidi_substream *substream;
unsigned int drain: 1, /* drain stage */
oss: 1; /* OSS compatible mode */
/* midi stream buffer */
@@ -79,7 +81,7 @@ struct snd_rawmidi_runtime {
/* event handler (new bytes, input only) */
void (*event)(struct snd_rawmidi_substream *substream);
/* defers calls to event [input] or ops->trigger [output] */
- struct tasklet_struct tasklet;
+ struct work_struct event_work;
/* private data */
void *private_data;
void (*private_free)(struct snd_rawmidi_substream *substream);
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index cbbed0db9e56..0757f542999d 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
(!substream->append || runtime->avail >= count);
}
-static void snd_rawmidi_input_event_tasklet(unsigned long data)
+static void snd_rawmidi_input_event_work(struct work_struct *work)
{
- struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
- substream->runtime->event(substream);
-}
-
-static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
-{
- struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
- substream->ops->trigger(substream, 1);
+ struct snd_rawmidi_runtime *runtime =
+ container_of(work, struct snd_rawmidi_runtime, event_work);
+ if (runtime->event)
+ runtime->event(runtime->substream);
}
static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
@@ -110,16 +106,10 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
return -ENOMEM;
+ runtime->substream = substream;
spin_lock_init(&runtime->lock);
init_waitqueue_head(&runtime->sleep);
- if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
- tasklet_init(&runtime->tasklet,
- snd_rawmidi_input_event_tasklet,
- (unsigned long)substream);
- else
- tasklet_init(&runtime->tasklet,
- snd_rawmidi_output_trigger_tasklet,
- (unsigned long)substream);
+ INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
runtime->event = NULL;
runtime->buffer_size = PAGE_SIZE;
runtime->avail_min = 1;
@@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
{
if (!substream->opened)
return;
- if (up) {
- tasklet_schedule(&substream->runtime->tasklet);
- } else {
- tasklet_kill(&substream->runtime->tasklet);
- substream->ops->trigger(substream, 0);
- }
+ substream->ops->trigger(substream, up);
}
static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -163,8 +148,8 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
if (!substream->opened)
return;
substream->ops->trigger(substream, up);
- if (!up && substream->runtime->event)
- tasklet_kill(&substream->runtime->tasklet);
+ if (!up)
+ cancel_work_sync(&substream->runtime->event_work);
}
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
@@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
}
if (result > 0) {
if (runtime->event)
- tasklet_schedule(&runtime->tasklet);
+ schedule_work(&runtime->event_work);
else if (snd_rawmidi_ready(substream))
wake_up(&runtime->sleep);
}