diff options
-rw-r--r-- | include/sound/rawmidi.h | 4 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 37 |
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 @@ | |||
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/workqueue.h> | ||
30 | 31 | ||
31 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 32 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) |
32 | #include "seq_device.h" | 33 | #include "seq_device.h" |
@@ -63,6 +64,7 @@ struct snd_rawmidi_global_ops { | |||
63 | }; | 64 | }; |
64 | 65 | ||
65 | struct snd_rawmidi_runtime { | 66 | struct snd_rawmidi_runtime { |
67 | struct snd_rawmidi_substream *substream; | ||
66 | unsigned int drain: 1, /* drain stage */ | 68 | unsigned int drain: 1, /* drain stage */ |
67 | oss: 1; /* OSS compatible mode */ | 69 | oss: 1; /* OSS compatible mode */ |
68 | /* midi stream buffer */ | 70 | /* midi stream buffer */ |
@@ -79,7 +81,7 @@ struct snd_rawmidi_runtime { | |||
79 | /* event handler (new bytes, input only) */ | 81 | /* event handler (new bytes, input only) */ |
80 | void (*event)(struct snd_rawmidi_substream *substream); | 82 | void (*event)(struct snd_rawmidi_substream *substream); |
81 | /* defers calls to event [input] or ops->trigger [output] */ | 83 | /* defers calls to event [input] or ops->trigger [output] */ |
82 | struct tasklet_struct tasklet; | 84 | struct work_struct event_work; |
83 | /* private data */ | 85 | /* private data */ |
84 | void *private_data; | 86 | void *private_data; |
85 | void (*private_free)(struct snd_rawmidi_substream *substream); | 87 | 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 | |||
92 | (!substream->append || runtime->avail >= count); | 92 | (!substream->append || runtime->avail >= count); |
93 | } | 93 | } |
94 | 94 | ||
95 | static void snd_rawmidi_input_event_tasklet(unsigned long data) | 95 | static void snd_rawmidi_input_event_work(struct work_struct *work) |
96 | { | 96 | { |
97 | struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data; | 97 | struct snd_rawmidi_runtime *runtime = |
98 | substream->runtime->event(substream); | 98 | container_of(work, struct snd_rawmidi_runtime, event_work); |
99 | } | 99 | if (runtime->event) |
100 | 100 | runtime->event(runtime->substream); | |
101 | static void snd_rawmidi_output_trigger_tasklet(unsigned long data) | ||
102 | { | ||
103 | struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data; | ||
104 | substream->ops->trigger(substream, 1); | ||
105 | } | 101 | } |
106 | 102 | ||
107 | static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) | 103 | 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) | |||
110 | 106 | ||
111 | if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL) | 107 | if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL) |
112 | return -ENOMEM; | 108 | return -ENOMEM; |
109 | runtime->substream = substream; | ||
113 | spin_lock_init(&runtime->lock); | 110 | spin_lock_init(&runtime->lock); |
114 | init_waitqueue_head(&runtime->sleep); | 111 | init_waitqueue_head(&runtime->sleep); |
115 | if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT) | 112 | INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work); |
116 | tasklet_init(&runtime->tasklet, | ||
117 | snd_rawmidi_input_event_tasklet, | ||
118 | (unsigned long)substream); | ||
119 | else | ||
120 | tasklet_init(&runtime->tasklet, | ||
121 | snd_rawmidi_output_trigger_tasklet, | ||
122 | (unsigned long)substream); | ||
123 | runtime->event = NULL; | 113 | runtime->event = NULL; |
124 | runtime->buffer_size = PAGE_SIZE; | 114 | runtime->buffer_size = PAGE_SIZE; |
125 | runtime->avail_min = 1; | 115 | runtime->avail_min = 1; |
@@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs | |||
150 | { | 140 | { |
151 | if (!substream->opened) | 141 | if (!substream->opened) |
152 | return; | 142 | return; |
153 | if (up) { | 143 | substream->ops->trigger(substream, up); |
154 | tasklet_schedule(&substream->runtime->tasklet); | ||
155 | } else { | ||
156 | tasklet_kill(&substream->runtime->tasklet); | ||
157 | substream->ops->trigger(substream, 0); | ||
158 | } | ||
159 | } | 144 | } |
160 | 145 | ||
161 | static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) | 146 | 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 | |||
163 | if (!substream->opened) | 148 | if (!substream->opened) |
164 | return; | 149 | return; |
165 | substream->ops->trigger(substream, up); | 150 | substream->ops->trigger(substream, up); |
166 | if (!up && substream->runtime->event) | 151 | if (!up) |
167 | tasklet_kill(&substream->runtime->tasklet); | 152 | cancel_work_sync(&substream->runtime->event_work); |
168 | } | 153 | } |
169 | 154 | ||
170 | int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream) | 155 | int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream) |
@@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, | |||
926 | } | 911 | } |
927 | if (result > 0) { | 912 | if (result > 0) { |
928 | if (runtime->event) | 913 | if (runtime->event) |
929 | tasklet_schedule(&runtime->tasklet); | 914 | schedule_work(&runtime->event_work); |
930 | else if (snd_rawmidi_ready(substream)) | 915 | else if (snd_rawmidi_ready(substream)) |
931 | wake_up(&runtime->sleep); | 916 | wake_up(&runtime->sleep); |
932 | } | 917 | } |