diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 20:20:18 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 20:20:18 -0700 |
commit | 7bfe0e66d5da32961f0060fc5d96b739b1ed64b9 (patch) | |
tree | 6d5dcf77248b574bb0c50930bbf9030aafb99fce /drivers/input/evdev.c | |
parent | 6a76a6992341faab0ef31e7d97000e0cf336d0ba (diff) | |
parent | 10ce3cc919f50c2043b41ca968b43c26a3672600 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov:
"- we finally merged driver for USB version of Synaptics touchpads
(I guess most commonly found in IBM/Lenovo keyboard/touchpad combo);
- a bunch of new drivers for embedded platforms (Cypress
touchscreens, DA9052 OnKey, MAX8997-haptic, Ilitek ILI210x
touchscreens, TI touchscreen);
- input core allows clients to specify desired clock source for
timestamps on input events (EVIOCSCLOCKID ioctl);
- input core allows querying state of all MT slots for given event
code via EVIOCGMTSLOTS ioctl;
- various driver fixes and improvements."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (45 commits)
Input: ili210x - add support for Ilitek ILI210x based touchscreens
Input: altera_ps2 - use of_match_ptr()
Input: synaptics_usb - switch to module_usb_driver()
Input: convert I2C drivers to use module_i2c_driver()
Input: convert SPI drivers to use module_spi_driver()
Input: omap4-keypad - move platform_data to <linux/platform_data>
Input: kxtj9 - who_am_i check value and initial data rate fixes
Input: add driver support for MAX8997-haptic
Input: tegra-kbc - revise device tree support
Input: of_keymap - add device tree bindings for simple key matrices
Input: wacom - fix physical size calculation for 3rd-gen Bamboo
Input: twl4030-vibra - really switch from #if to #ifdef
Input: hp680_ts_input - ensure arguments to request_irq and free_irq are compatible
Input: max8925_onkey - avoid accessing input device too early
Input: max8925_onkey - allow to be used as a wakeup source
Input: atmel-wm97xx - convert to dev_pm_ops
Input: atmel-wm97xx - set driver owner
Input: add cyttsp touchscreen maintainer entry
Input: cyttsp - remove useless checks in cyttsp_probe()
Input: usbtouchscreen - add support for Data Modul EasyTouch TP 72037
...
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r-- | drivers/input/evdev.c | 52 |
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 @@ #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,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[]; }; @@ -54,8 +55,12 @@ static struct evdev *evdev_table[EVDEV_MINORS]; 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); @@ -94,8 +99,11 @@ static void evdev_event(struct input_handle *handle, 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; @@ -103,11 +111,12 @@ static void evdev_event(struct input_handle *handle, 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(); @@ -623,6 +632,28 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) 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) { @@ -685,6 +716,14 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, 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); @@ -708,6 +747,9 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, 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); |