aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 7df5bfef2624..4b2e10d5d641 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -20,7 +20,7 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/input.h> 23#include <linux/input/mt.h>
24#include <linux/major.h> 24#include <linux/major.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include "input-compat.h" 26#include "input-compat.h"
@@ -46,6 +46,7 @@ struct evdev_client {
46 struct fasync_struct *fasync; 46 struct fasync_struct *fasync;
47 struct evdev *evdev; 47 struct evdev *evdev;
48 struct list_head node; 48 struct list_head node;
49 int clkid;
49 unsigned int bufsize; 50 unsigned int bufsize;
50 struct input_event buffer[]; 51 struct input_event buffer[];
51}; 52};
@@ -54,8 +55,12 @@ static struct evdev *evdev_table[EVDEV_MINORS];
54static DEFINE_MUTEX(evdev_table_mutex); 55static DEFINE_MUTEX(evdev_table_mutex);
55 56
56static void evdev_pass_event(struct evdev_client *client, 57static void evdev_pass_event(struct evdev_client *client,
57 struct input_event *event) 58 struct input_event *event,
59 ktime_t mono, ktime_t real)
58{ 60{
61 event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
62 mono : real);
63
59 /* Interrupts are disabled, just acquire the lock. */ 64 /* Interrupts are disabled, just acquire the lock. */
60 spin_lock(&client->buffer_lock); 65 spin_lock(&client->buffer_lock);
61 66
@@ -94,8 +99,11 @@ static void evdev_event(struct input_handle *handle,
94 struct evdev *evdev = handle->private; 99 struct evdev *evdev = handle->private;
95 struct evdev_client *client; 100 struct evdev_client *client;
96 struct input_event event; 101 struct input_event event;
102 ktime_t time_mono, time_real;
103
104 time_mono = ktime_get();
105 time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());
97 106
98 do_gettimeofday(&event.time);
99 event.type = type; 107 event.type = type;
100 event.code = code; 108 event.code = code;
101 event.value = value; 109 event.value = value;
@@ -103,11 +111,12 @@ static void evdev_event(struct input_handle *handle,
103 rcu_read_lock(); 111 rcu_read_lock();
104 112
105 client = rcu_dereference(evdev->grab); 113 client = rcu_dereference(evdev->grab);
114
106 if (client) 115 if (client)
107 evdev_pass_event(client, &event); 116 evdev_pass_event(client, &event, time_mono, time_real);
108 else 117 else
109 list_for_each_entry_rcu(client, &evdev->client_list, node) 118 list_for_each_entry_rcu(client, &evdev->client_list, node)
110 evdev_pass_event(client, &event); 119 evdev_pass_event(client, &event, time_mono, time_real);
111 120
112 rcu_read_unlock(); 121 rcu_read_unlock();
113 122
@@ -623,6 +632,28 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
623 return input_set_keycode(dev, &ke); 632 return input_set_keycode(dev, &ke);
624} 633}
625 634
635static int evdev_handle_mt_request(struct input_dev *dev,
636 unsigned int size,
637 int __user *ip)
638{
639 const struct input_mt_slot *mt = dev->mt;
640 unsigned int code;
641 int max_slots;
642 int i;
643
644 if (get_user(code, &ip[0]))
645 return -EFAULT;
646 if (!input_is_mt_value(code))
647 return -EINVAL;
648
649 max_slots = (size - sizeof(__u32)) / sizeof(__s32);
650 for (i = 0; i < dev->mtsize && i < max_slots; i++)
651 if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i]))
652 return -EFAULT;
653
654 return 0;
655}
656
626static long evdev_do_ioctl(struct file *file, unsigned int cmd, 657static long evdev_do_ioctl(struct file *file, unsigned int cmd,
627 void __user *p, int compat_mode) 658 void __user *p, int compat_mode)
628{ 659{
@@ -685,6 +716,14 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
685 else 716 else
686 return evdev_ungrab(evdev, client); 717 return evdev_ungrab(evdev, client);
687 718
719 case EVIOCSCLOCKID:
720 if (copy_from_user(&i, p, sizeof(unsigned int)))
721 return -EFAULT;
722 if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
723 return -EINVAL;
724 client->clkid = i;
725 return 0;
726
688 case EVIOCGKEYCODE: 727 case EVIOCGKEYCODE:
689 return evdev_handle_get_keycode(dev, p); 728 return evdev_handle_get_keycode(dev, p);
690 729
@@ -708,6 +747,9 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
708 return bits_to_user(dev->propbit, INPUT_PROP_MAX, 747 return bits_to_user(dev->propbit, INPUT_PROP_MAX,
709 size, p, compat_mode); 748 size, p, compat_mode);
710 749
750 case EVIOCGMTSLOTS(0):
751 return evdev_handle_mt_request(dev, size, ip);
752
711 case EVIOCGKEY(0): 753 case EVIOCGKEY(0):
712 return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); 754 return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
713 755