Merge branch 'for-next' of github.com:rydberg/linux into next
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 9 Mar 2012 18:56:35 +0000 (10:56 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 9 Mar 2012 18:56:35 +0000 (10:56 -0800)
1  2 
drivers/input/evdev.c
include/linux/input.h

diff --combined drivers/input/evdev.c
index 3626b1ce46095d367d0d34c800367ef60b637820,e4cad161be9d832d5baeaabe047024c2dbe4332e..cfe78597eb68d7be98472f7d86f2661d60e3f8d7
@@@ -20,7 -20,7 +20,7 @@@
  #include <linux/slab.h>
  #include <linux/module.h>
  #include <linux/init.h>
- #include <linux/input.h>
+ #include <linux/input/mt.h>
  #include <linux/major.h>
  #include <linux/device.h>
  #include "input-compat.h"
@@@ -46,7 -46,6 +46,7 @@@ struct evdev_client 
        struct fasync_struct *fasync;
        struct evdev *evdev;
        struct list_head node;
 +      int clkid;
        unsigned int bufsize;
        struct input_event buffer[];
  };
@@@ -55,12 -54,8 +55,12 @@@ static struct evdev *evdev_table[EVDEV_
  static DEFINE_MUTEX(evdev_table_mutex);
  
  static void evdev_pass_event(struct evdev_client *client,
 -                           struct input_event *event)
 +                           struct input_event *event,
 +                           ktime_t mono, ktime_t real)
  {
 +      event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
 +                                      mono : real);
 +
        /* Interrupts are disabled, just acquire the lock. */
        spin_lock(&client->buffer_lock);
  
@@@ -99,11 -94,8 +99,11 @@@ static void evdev_event(struct input_ha
        struct evdev *evdev = handle->private;
        struct evdev_client *client;
        struct input_event event;
 +      ktime_t time_mono, time_real;
 +
 +      time_mono = ktime_get();
 +      time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());
  
 -      do_gettimeofday(&event.time);
        event.type = type;
        event.code = code;
        event.value = value;
        rcu_read_lock();
  
        client = rcu_dereference(evdev->grab);
 +
        if (client)
 -              evdev_pass_event(client, &event);
 +              evdev_pass_event(client, &event, time_mono, time_real);
        else
                list_for_each_entry_rcu(client, &evdev->client_list, node)
 -                      evdev_pass_event(client, &event);
 +                      evdev_pass_event(client, &event, time_mono, time_real);
  
        rcu_read_unlock();
  
@@@ -395,7 -386,7 +395,7 @@@ static ssize_t evdev_read(struct file *
        struct evdev_client *client = file->private_data;
        struct evdev *evdev = client->evdev;
        struct input_event event;
 -      int retval;
 +      int retval = 0;
  
        if (count < input_event_size())
                return -EINVAL;
@@@ -632,6 -623,28 +632,28 @@@ static int evdev_handle_set_keycode_v2(
        return input_set_keycode(dev, &ke);
  }
  
+ static int evdev_handle_mt_request(struct input_dev *dev,
+                                  unsigned int size,
+                                  int __user *ip)
+ {
+       const struct input_mt_slot *mt = dev->mt;
+       unsigned int code;
+       int max_slots;
+       int i;
+       if (get_user(code, &ip[0]))
+               return -EFAULT;
+       if (!input_is_mt_value(code))
+               return -EINVAL;
+       max_slots = (size - sizeof(__u32)) / sizeof(__s32);
+       for (i = 0; i < dev->mtsize && i < max_slots; i++)
+               if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i]))
+                       return -EFAULT;
+       return 0;
+ }
  static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                           void __user *p, int compat_mode)
  {
                else
                        return evdev_ungrab(evdev, client);
  
 +      case EVIOCSCLOCKID:
 +              if (copy_from_user(&i, p, sizeof(unsigned int)))
 +                      return -EFAULT;
 +              if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
 +                      return -EINVAL;
 +              client->clkid = i;
 +              return 0;
 +
        case EVIOCGKEYCODE:
                return evdev_handle_get_keycode(dev, p);
  
                return bits_to_user(dev->propbit, INPUT_PROP_MAX,
                                    size, p, compat_mode);
  
+       case EVIOCGMTSLOTS(0):
+               return evdev_handle_mt_request(dev, size, ip);
        case EVIOCGKEY(0):
                return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
  
diff --combined include/linux/input.h
index 177261ea6f5216b3c228c804e18f5e1101df5e4e,af264438631d7a47d17f96484e943c7babf415eb..a81671453575d800ec3d102e1aa6a8bf517073ce
@@@ -114,6 -114,31 +114,31 @@@ struct input_keymap_entry 
  #define EVIOCGUNIQ(len)               _IOC(_IOC_READ, 'E', 0x08, len)         /* get unique identifier */
  #define EVIOCGPROP(len)               _IOC(_IOC_READ, 'E', 0x09, len)         /* get device properties */
  
+ /**
+  * EVIOCGMTSLOTS(len) - get MT slot values
+  *
+  * The ioctl buffer argument should be binary equivalent to
+  *
+  * struct input_mt_request_layout {
+  *    __u32 code;
+  *    __s32 values[num_slots];
+  * };
+  *
+  * where num_slots is the (arbitrary) number of MT slots to extract.
+  *
+  * The ioctl size argument (len) is the size of the buffer, which
+  * should satisfy len = (num_slots + 1) * sizeof(__s32).  If len is
+  * too small to fit all available slots, the first num_slots are
+  * returned.
+  *
+  * Before the call, code is set to the wanted ABS_MT event type. On
+  * return, values[] is filled with the slot values for the specified
+  * ABS_MT code.
+  *
+  * If the request code is not an ABS_MT value, -EINVAL is returned.
+  */
+ #define EVIOCGMTSLOTS(len)    _IOC(_IOC_READ, 'E', 0x0a, len)
  #define EVIOCGKEY(len)                _IOC(_IOC_READ, 'E', 0x18, len)         /* get global key state */
  #define EVIOCGLED(len)                _IOC(_IOC_READ, 'E', 0x19, len)         /* get all LEDs */
  #define EVIOCGSND(len)                _IOC(_IOC_READ, 'E', 0x1a, len)         /* get all sounds status */
  
  #define EVIOCGRAB             _IOW('E', 0x90, int)                    /* Grab/Release device */
  
 +#define EVIOCSCLOCKID         _IOW('E', 0xa0, int)                    /* Set clockid to be used for timestamps */
 +
  /*
   * Device properties and quirks
   */