|
@@ -61,7 +61,6 @@ struct ml_device {
|
|
|
struct ml_effect_state states[FF_MEMLESS_EFFECTS];
|
|
|
int gain;
|
|
|
struct timer_list timer;
|
|
|
- spinlock_t timer_lock;
|
|
|
struct input_dev *dev;
|
|
|
|
|
|
int (*play_effect)(struct input_dev *dev, void *data,
|
|
@@ -368,38 +367,38 @@ static void ml_effect_timer(unsigned long timer_data)
|
|
|
{
|
|
|
struct input_dev *dev = (struct input_dev *)timer_data;
|
|
|
struct ml_device *ml = dev->ff->private;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
debug("timer: updating effects");
|
|
|
|
|
|
- spin_lock(&ml->timer_lock);
|
|
|
+ spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
ml_play_effects(ml);
|
|
|
- spin_unlock(&ml->timer_lock);
|
|
|
+ spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Sets requested gain for FF effects. Called with dev->event_lock held.
|
|
|
+ */
|
|
|
static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
|
|
|
{
|
|
|
struct ml_device *ml = dev->ff->private;
|
|
|
int i;
|
|
|
|
|
|
- spin_lock_bh(&ml->timer_lock);
|
|
|
-
|
|
|
ml->gain = gain;
|
|
|
|
|
|
for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
|
|
|
__clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
|
|
|
|
|
|
ml_play_effects(ml);
|
|
|
-
|
|
|
- spin_unlock_bh(&ml->timer_lock);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Start/stop specified FF effect. Called with dev->event_lock held.
|
|
|
+ */
|
|
|
static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
|
|
|
{
|
|
|
struct ml_device *ml = dev->ff->private;
|
|
|
struct ml_effect_state *state = &ml->states[effect_id];
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- spin_lock_irqsave(&ml->timer_lock, flags);
|
|
|
|
|
|
if (value > 0) {
|
|
|
debug("initiated play");
|
|
@@ -425,8 +424,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
|
|
|
ml_play_effects(ml);
|
|
|
}
|
|
|
|
|
|
- spin_unlock_irqrestore(&ml->timer_lock, flags);
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -436,7 +433,7 @@ static int ml_ff_upload(struct input_dev *dev,
|
|
|
struct ml_device *ml = dev->ff->private;
|
|
|
struct ml_effect_state *state = &ml->states[effect->id];
|
|
|
|
|
|
- spin_lock_bh(&ml->timer_lock);
|
|
|
+ spin_lock_irq(&dev->event_lock);
|
|
|
|
|
|
if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
|
|
|
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
|
|
@@ -448,7 +445,7 @@ static int ml_ff_upload(struct input_dev *dev,
|
|
|
ml_schedule_timer(ml);
|
|
|
}
|
|
|
|
|
|
- spin_unlock_bh(&ml->timer_lock);
|
|
|
+ spin_unlock_irq(&dev->event_lock);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -482,7 +479,6 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
|
|
|
ml->private = data;
|
|
|
ml->play_effect = play_effect;
|
|
|
ml->gain = 0xffff;
|
|
|
- spin_lock_init(&ml->timer_lock);
|
|
|
setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
|
|
|
|
|
|
set_bit(FF_GAIN, dev->ffbit);
|