diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-06-26 11:30:02 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2008-06-30 09:26:02 -0400 |
commit | 656acd2bbc4ce7f224de499ee255698701396c48 (patch) | |
tree | 8a6b0077d0bec8fec96ae3dfe28389c2909e6051 | |
parent | 4bbff7e408a54cce88d26191191e8bcda2a60d55 (diff) |
Input: fix locking in force-feedback core
The newly added event_lock spinlock in the input core disallows sleeping
and therefore using mutexes in event handlers. Convert force-feedback
core to rely on event_lock instead of mutex to protect slots allocated
for fore-feedback effects. The original mutex is still used to serialize
uploading and erasing of effects.
Reported-by: Anssi Hannula <anssi.hannula@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/ff-core.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index eebc72465fc9..4c01464ec8f3 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c | |||
@@ -166,8 +166,10 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, | |||
166 | if (ret) | 166 | if (ret) |
167 | goto out; | 167 | goto out; |
168 | 168 | ||
169 | spin_lock_irq(&dev->event_lock); | ||
169 | ff->effects[id] = *effect; | 170 | ff->effects[id] = *effect; |
170 | ff->effect_owners[id] = file; | 171 | ff->effect_owners[id] = file; |
172 | spin_unlock_irq(&dev->event_lock); | ||
171 | 173 | ||
172 | out: | 174 | out: |
173 | mutex_unlock(&ff->mutex); | 175 | mutex_unlock(&ff->mutex); |
@@ -189,16 +191,22 @@ static int erase_effect(struct input_dev *dev, int effect_id, | |||
189 | if (error) | 191 | if (error) |
190 | return error; | 192 | return error; |
191 | 193 | ||
194 | spin_lock_irq(&dev->event_lock); | ||
192 | ff->playback(dev, effect_id, 0); | 195 | ff->playback(dev, effect_id, 0); |
196 | ff->effect_owners[effect_id] = NULL; | ||
197 | spin_unlock_irq(&dev->event_lock); | ||
193 | 198 | ||
194 | if (ff->erase) { | 199 | if (ff->erase) { |
195 | error = ff->erase(dev, effect_id); | 200 | error = ff->erase(dev, effect_id); |
196 | if (error) | 201 | if (error) { |
202 | spin_lock_irq(&dev->event_lock); | ||
203 | ff->effect_owners[effect_id] = file; | ||
204 | spin_unlock_irq(&dev->event_lock); | ||
205 | |||
197 | return error; | 206 | return error; |
207 | } | ||
198 | } | 208 | } |
199 | 209 | ||
200 | ff->effect_owners[effect_id] = NULL; | ||
201 | |||
202 | return 0; | 210 | return 0; |
203 | } | 211 | } |
204 | 212 | ||
@@ -263,8 +271,6 @@ int input_ff_event(struct input_dev *dev, unsigned int type, | |||
263 | if (type != EV_FF) | 271 | if (type != EV_FF) |
264 | return 0; | 272 | return 0; |
265 | 273 | ||
266 | mutex_lock(&ff->mutex); | ||
267 | |||
268 | switch (code) { | 274 | switch (code) { |
269 | case FF_GAIN: | 275 | case FF_GAIN: |
270 | if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff) | 276 | if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff) |
@@ -286,7 +292,6 @@ int input_ff_event(struct input_dev *dev, unsigned int type, | |||
286 | break; | 292 | break; |
287 | } | 293 | } |
288 | 294 | ||
289 | mutex_unlock(&ff->mutex); | ||
290 | return 0; | 295 | return 0; |
291 | } | 296 | } |
292 | EXPORT_SYMBOL_GPL(input_ff_event); | 297 | EXPORT_SYMBOL_GPL(input_ff_event); |