diff options
author | Atif Niyaz <atifniyaz@google.com> | 2019-07-24 15:26:31 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-07-25 04:12:20 -0400 |
commit | 3b51c44bd6936e86a7180abd9aebc4387a479253 (patch) | |
tree | 307baa973004837a30e57d0a3dccc54f89e06604 /drivers/input/evdev.c | |
parent | c2433827c1a149b72f1413f0151155f6fa4b3214 (diff) |
Input: allow drivers specify timestamp for input events
Currently, evdev stamps events with timestamps acquired in evdev_events()
However, this timestamping may not be accurate in terms of measuring
when the actual event happened.
Let's allow individual drivers specify timestamp in order to provide a more
accurate sense of time for the event. It is expected that drivers will set the
timestamp in their hard interrupt routine.
Signed-off-by: Atif Niyaz <atifniyaz@google.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r-- | drivers/input/evdev.c | 35 |
1 files changed, 8 insertions, 27 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 867c2cfd0038..d7dd6fcf2db0 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -25,13 +25,6 @@ | |||
25 | #include <linux/cdev.h> | 25 | #include <linux/cdev.h> |
26 | #include "input-compat.h" | 26 | #include "input-compat.h" |
27 | 27 | ||
28 | enum evdev_clock_type { | ||
29 | EV_CLK_REAL = 0, | ||
30 | EV_CLK_MONO, | ||
31 | EV_CLK_BOOT, | ||
32 | EV_CLK_MAX | ||
33 | }; | ||
34 | |||
35 | struct evdev { | 28 | struct evdev { |
36 | int open; | 29 | int open; |
37 | struct input_handle handle; | 30 | struct input_handle handle; |
@@ -53,7 +46,7 @@ struct evdev_client { | |||
53 | struct fasync_struct *fasync; | 46 | struct fasync_struct *fasync; |
54 | struct evdev *evdev; | 47 | struct evdev *evdev; |
55 | struct list_head node; | 48 | struct list_head node; |
56 | unsigned int clk_type; | 49 | enum input_clock_type clk_type; |
57 | bool revoked; | 50 | bool revoked; |
58 | unsigned long *evmasks[EV_CNT]; | 51 | unsigned long *evmasks[EV_CNT]; |
59 | unsigned int bufsize; | 52 | unsigned int bufsize; |
@@ -149,17 +142,10 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) | |||
149 | 142 | ||
150 | static void __evdev_queue_syn_dropped(struct evdev_client *client) | 143 | static void __evdev_queue_syn_dropped(struct evdev_client *client) |
151 | { | 144 | { |
145 | ktime_t *ev_time = input_get_timestamp(client->evdev->handle.dev); | ||
146 | struct timespec64 ts = ktime_to_timespec64(ev_time[client->clk_type]); | ||
152 | struct input_event ev; | 147 | struct input_event ev; |
153 | ktime_t time; | ||
154 | struct timespec64 ts; | ||
155 | 148 | ||
156 | time = client->clk_type == EV_CLK_REAL ? | ||
157 | ktime_get_real() : | ||
158 | client->clk_type == EV_CLK_MONO ? | ||
159 | ktime_get() : | ||
160 | ktime_get_boottime(); | ||
161 | |||
162 | ts = ktime_to_timespec64(time); | ||
163 | ev.input_event_sec = ts.tv_sec; | 149 | ev.input_event_sec = ts.tv_sec; |
164 | ev.input_event_usec = ts.tv_nsec / NSEC_PER_USEC; | 150 | ev.input_event_usec = ts.tv_nsec / NSEC_PER_USEC; |
165 | ev.type = EV_SYN; | 151 | ev.type = EV_SYN; |
@@ -188,18 +174,18 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) | |||
188 | static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) | 174 | static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) |
189 | { | 175 | { |
190 | unsigned long flags; | 176 | unsigned long flags; |
191 | unsigned int clk_type; | 177 | enum input_clock_type clk_type; |
192 | 178 | ||
193 | switch (clkid) { | 179 | switch (clkid) { |
194 | 180 | ||
195 | case CLOCK_REALTIME: | 181 | case CLOCK_REALTIME: |
196 | clk_type = EV_CLK_REAL; | 182 | clk_type = INPUT_CLK_REAL; |
197 | break; | 183 | break; |
198 | case CLOCK_MONOTONIC: | 184 | case CLOCK_MONOTONIC: |
199 | clk_type = EV_CLK_MONO; | 185 | clk_type = INPUT_CLK_MONO; |
200 | break; | 186 | break; |
201 | case CLOCK_BOOTTIME: | 187 | case CLOCK_BOOTTIME: |
202 | clk_type = EV_CLK_BOOT; | 188 | clk_type = INPUT_CLK_BOOT; |
203 | break; | 189 | break; |
204 | default: | 190 | default: |
205 | return -EINVAL; | 191 | return -EINVAL; |
@@ -307,12 +293,7 @@ static void evdev_events(struct input_handle *handle, | |||
307 | { | 293 | { |
308 | struct evdev *evdev = handle->private; | 294 | struct evdev *evdev = handle->private; |
309 | struct evdev_client *client; | 295 | struct evdev_client *client; |
310 | ktime_t ev_time[EV_CLK_MAX]; | 296 | ktime_t *ev_time = input_get_timestamp(handle->dev); |
311 | |||
312 | ev_time[EV_CLK_MONO] = ktime_get(); | ||
313 | ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); | ||
314 | ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO], | ||
315 | TK_OFFS_BOOT); | ||
316 | 297 | ||
317 | rcu_read_lock(); | 298 | rcu_read_lock(); |
318 | 299 | ||