Implement a new force feedback interface, in which all non-driver-specific
operations are separated to a common module. This includes handling effect
type validations, effect timers, locking, etc.
The code should be built as part of the input module, but unfortunately that
would require renaming input.c, which we don't want to do. So instead we make
INPUT_FF_EFFECTS a bool so that it cannot be built as a module.
@@ -865,6 +865,9 @@ struct input_dev {
unsigned long sndbit[NBITS(SND_MAX)];
unsigned long ffbit[NBITS(FF_MAX)];
unsigned long swbit[NBITS(SW_MAX)];
+
+ struct ff_device *ff;
+ struct mutex ff_lock;
===================================================================
--- linux-2.6.17-rc4-git12.orig/drivers/input/input.c 2006-05-27 02:28:57.000000000 +0300
+++ linux-2.6.17-rc4-git12/drivers/input/input.c 2006-05-27 02:38:35.000000000 +0300
@@ -733,6 +733,17 @@ static void input_dev_release(struct cla
{
struct input_dev *dev = to_input_dev(class_dev);
+ if (dev->ff) {
+ struct ff_device *ff = dev->ff;
+ clear_bit(EV_FF, dev->evbit);
+ mutex_lock(&dev->ff_lock);
+ del_timer_sync(&ff->timer);
+ dev->flush = NULL;
+ dev->ff = NULL;
+ mutex_unlock(&dev->ff_lock);
+ kfree(ff);
+ }
+
kfree(dev);
module_put(THIS_MODULE);
}
+static inline int input_ff_safe_lock(struct input_dev *dev)
+{
+ mutex_lock(&dev->ff_lock);
+ if (dev->ff)
+ return 0;
+
+ mutex_unlock(&dev->ff_lock);
+ return 1;
+}
+static void input_ff_calc_timer(struct ff_device *ff)...
+{
+ int i;
+ int events = 0;
+ unsigned long next_time = 0;
+
+ if (time_after(jiffies, event_time)) {
+ event_time = jiffies;
+
+/**
+ * abs() with -0x8000 => 0x7fff exception
+ */
+static inline u16 input_ff_unsign(s16 value)
+{
+ if (value == -0x8000)
+ return 0x7fff;
+
+ return (value < 0 ? -value : value);
+}
+
+/**
+ * Safe sum
+ * @a: Integer to sum
+ * @b: Integer to sum
+ * @limit: The sum limit
+ *
+ * If @a+@b is above @limit, return @limit
+ */
+static int input_ff_safe_sum(int a, int b, int limit)
+{
+ int c;
+ if (!a)
+ return b;
+ c = a + b;
+ if (c > limit)
+ return limit;
+ return c;
+}