mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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>
This commit is contained in:
parent
30bdee0259
commit
b3c705aa9e
2 changed files with 14 additions and 27 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
|
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
|
||||||
#include "seq_device.h"
|
#include "seq_device.h"
|
||||||
|
@ -63,6 +64,7 @@ struct snd_rawmidi_global_ops {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snd_rawmidi_runtime {
|
struct snd_rawmidi_runtime {
|
||||||
|
struct snd_rawmidi_substream *substream;
|
||||||
unsigned int drain: 1, /* drain stage */
|
unsigned int drain: 1, /* drain stage */
|
||||||
oss: 1; /* OSS compatible mode */
|
oss: 1; /* OSS compatible mode */
|
||||||
/* midi stream buffer */
|
/* midi stream buffer */
|
||||||
|
@ -79,7 +81,7 @@ struct snd_rawmidi_runtime {
|
||||||
/* event handler (new bytes, input only) */
|
/* event handler (new bytes, input only) */
|
||||||
void (*event)(struct snd_rawmidi_substream *substream);
|
void (*event)(struct snd_rawmidi_substream *substream);
|
||||||
/* defers calls to event [input] or ops->trigger [output] */
|
/* defers calls to event [input] or ops->trigger [output] */
|
||||||
struct tasklet_struct tasklet;
|
struct work_struct event_work;
|
||||||
/* private data */
|
/* private data */
|
||||||
void *private_data;
|
void *private_data;
|
||||||
void (*private_free)(struct snd_rawmidi_substream *substream);
|
void (*private_free)(struct snd_rawmidi_substream *substream);
|
||||||
|
|
|
@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
|
||||||
(!substream->append || runtime->avail >= count);
|
(!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;
|
struct snd_rawmidi_runtime *runtime =
|
||||||
substream->runtime->event(substream);
|
container_of(work, struct snd_rawmidi_runtime, event_work);
|
||||||
}
|
if (runtime->event)
|
||||||
|
runtime->event(runtime->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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *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)
|
if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
runtime->substream = substream;
|
||||||
spin_lock_init(&runtime->lock);
|
spin_lock_init(&runtime->lock);
|
||||||
init_waitqueue_head(&runtime->sleep);
|
init_waitqueue_head(&runtime->sleep);
|
||||||
if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
|
INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
|
||||||
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);
|
|
||||||
runtime->event = NULL;
|
runtime->event = NULL;
|
||||||
runtime->buffer_size = PAGE_SIZE;
|
runtime->buffer_size = PAGE_SIZE;
|
||||||
runtime->avail_min = 1;
|
runtime->avail_min = 1;
|
||||||
|
@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
|
||||||
{
|
{
|
||||||
if (!substream->opened)
|
if (!substream->opened)
|
||||||
return;
|
return;
|
||||||
if (up) {
|
substream->ops->trigger(substream, up);
|
||||||
tasklet_schedule(&substream->runtime->tasklet);
|
|
||||||
} else {
|
|
||||||
tasklet_kill(&substream->runtime->tasklet);
|
|
||||||
substream->ops->trigger(substream, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int 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)
|
if (!substream->opened)
|
||||||
return;
|
return;
|
||||||
substream->ops->trigger(substream, up);
|
substream->ops->trigger(substream, up);
|
||||||
if (!up && substream->runtime->event)
|
if (!up)
|
||||||
tasklet_kill(&substream->runtime->tasklet);
|
cancel_work_sync(&substream->runtime->event_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
|
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 (result > 0) {
|
||||||
if (runtime->event)
|
if (runtime->event)
|
||||||
tasklet_schedule(&runtime->tasklet);
|
schedule_work(&runtime->event_work);
|
||||||
else if (snd_rawmidi_ready(substream))
|
else if (snd_rawmidi_ready(substream))
|
||||||
wake_up(&runtime->sleep);
|
wake_up(&runtime->sleep);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue