aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/keyboard/gpio_keys.c17
-rw-r--r--drivers/input/misc/xen-kbdfront.c219
-rw-r--r--drivers/input/serio/i8042.c12
3 files changed, 204 insertions, 44 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index da3d362f21b1..a047b9af8369 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -48,6 +48,7 @@ struct gpio_button_data {
48 spinlock_t lock; 48 spinlock_t lock;
49 bool disabled; 49 bool disabled;
50 bool key_pressed; 50 bool key_pressed;
51 bool suspended;
51}; 52};
52 53
53struct gpio_keys_drvdata { 54struct gpio_keys_drvdata {
@@ -396,8 +397,20 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
396 397
397 BUG_ON(irq != bdata->irq); 398 BUG_ON(irq != bdata->irq);
398 399
399 if (bdata->button->wakeup) 400 if (bdata->button->wakeup) {
401 const struct gpio_keys_button *button = bdata->button;
402
400 pm_stay_awake(bdata->input->dev.parent); 403 pm_stay_awake(bdata->input->dev.parent);
404 if (bdata->suspended &&
405 (button->type == 0 || button->type == EV_KEY)) {
406 /*
407 * Simulate wakeup key press in case the key has
408 * already released by the time we got interrupt
409 * handler to run.
410 */
411 input_report_key(bdata->input, button->code, 1);
412 }
413 }
401 414
402 mod_delayed_work(system_wq, 415 mod_delayed_work(system_wq,
403 &bdata->work, 416 &bdata->work,
@@ -855,6 +868,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
855 struct gpio_button_data *bdata = &ddata->data[i]; 868 struct gpio_button_data *bdata = &ddata->data[i];
856 if (bdata->button->wakeup) 869 if (bdata->button->wakeup)
857 enable_irq_wake(bdata->irq); 870 enable_irq_wake(bdata->irq);
871 bdata->suspended = true;
858 } 872 }
859 } else { 873 } else {
860 mutex_lock(&input->mutex); 874 mutex_lock(&input->mutex);
@@ -878,6 +892,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
878 struct gpio_button_data *bdata = &ddata->data[i]; 892 struct gpio_button_data *bdata = &ddata->data[i];
879 if (bdata->button->wakeup) 893 if (bdata->button->wakeup)
880 disable_irq_wake(bdata->irq); 894 disable_irq_wake(bdata->irq);
895 bdata->suspended = false;
881 } 896 }
882 } else { 897 } else {
883 mutex_lock(&input->mutex); 898 mutex_lock(&input->mutex);
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index eb770613a9bd..fa130e7b734c 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/input.h> 19#include <linux/input.h>
20#include <linux/input/mt.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21 22
22#include <asm/xen/hypervisor.h> 23#include <asm/xen/hypervisor.h>
@@ -34,11 +35,14 @@
34struct xenkbd_info { 35struct xenkbd_info {
35 struct input_dev *kbd; 36 struct input_dev *kbd;
36 struct input_dev *ptr; 37 struct input_dev *ptr;
38 struct input_dev *mtouch;
37 struct xenkbd_page *page; 39 struct xenkbd_page *page;
38 int gref; 40 int gref;
39 int irq; 41 int irq;
40 struct xenbus_device *xbdev; 42 struct xenbus_device *xbdev;
41 char phys[32]; 43 char phys[32];
44 /* current MT slot/contact ID we are injecting events in */
45 int mtouch_cur_contact_id;
42}; 46};
43 47
44enum { KPARAM_X, KPARAM_Y, KPARAM_CNT }; 48enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
@@ -56,6 +60,112 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *);
56 * to do that. 60 * to do that.
57 */ 61 */
58 62
63static void xenkbd_handle_motion_event(struct xenkbd_info *info,
64 struct xenkbd_motion *motion)
65{
66 input_report_rel(info->ptr, REL_X, motion->rel_x);
67 input_report_rel(info->ptr, REL_Y, motion->rel_y);
68 if (motion->rel_z)
69 input_report_rel(info->ptr, REL_WHEEL, -motion->rel_z);
70 input_sync(info->ptr);
71}
72
73static void xenkbd_handle_position_event(struct xenkbd_info *info,
74 struct xenkbd_position *pos)
75{
76 input_report_abs(info->ptr, ABS_X, pos->abs_x);
77 input_report_abs(info->ptr, ABS_Y, pos->abs_y);
78 if (pos->rel_z)
79 input_report_rel(info->ptr, REL_WHEEL, -pos->rel_z);
80 input_sync(info->ptr);
81}
82
83static void xenkbd_handle_key_event(struct xenkbd_info *info,
84 struct xenkbd_key *key)
85{
86 struct input_dev *dev;
87
88 if (test_bit(key->keycode, info->ptr->keybit)) {
89 dev = info->ptr;
90 } else if (test_bit(key->keycode, info->kbd->keybit)) {
91 dev = info->kbd;
92 } else {
93 pr_warn("unhandled keycode 0x%x\n", key->keycode);
94 return;
95 }
96
97 input_report_key(dev, key->keycode, key->pressed);
98 input_sync(dev);
99}
100
101static void xenkbd_handle_mt_event(struct xenkbd_info *info,
102 struct xenkbd_mtouch *mtouch)
103{
104 if (unlikely(!info->mtouch))
105 return;
106
107 if (mtouch->contact_id != info->mtouch_cur_contact_id) {
108 info->mtouch_cur_contact_id = mtouch->contact_id;
109 input_mt_slot(info->mtouch, mtouch->contact_id);
110 }
111
112 switch (mtouch->event_type) {
113 case XENKBD_MT_EV_DOWN:
114 input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, true);
115 /* fall through */
116
117 case XENKBD_MT_EV_MOTION:
118 input_report_abs(info->mtouch, ABS_MT_POSITION_X,
119 mtouch->u.pos.abs_x);
120 input_report_abs(info->mtouch, ABS_MT_POSITION_Y,
121 mtouch->u.pos.abs_y);
122 break;
123
124 case XENKBD_MT_EV_SHAPE:
125 input_report_abs(info->mtouch, ABS_MT_TOUCH_MAJOR,
126 mtouch->u.shape.major);
127 input_report_abs(info->mtouch, ABS_MT_TOUCH_MINOR,
128 mtouch->u.shape.minor);
129 break;
130
131 case XENKBD_MT_EV_ORIENT:
132 input_report_abs(info->mtouch, ABS_MT_ORIENTATION,
133 mtouch->u.orientation);
134 break;
135
136 case XENKBD_MT_EV_UP:
137 input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false);
138 break;
139
140 case XENKBD_MT_EV_SYN:
141 input_mt_sync_frame(info->mtouch);
142 input_sync(info->mtouch);
143 break;
144 }
145}
146
147static void xenkbd_handle_event(struct xenkbd_info *info,
148 union xenkbd_in_event *event)
149{
150 switch (event->type) {
151 case XENKBD_TYPE_MOTION:
152 xenkbd_handle_motion_event(info, &event->motion);
153 break;
154
155 case XENKBD_TYPE_KEY:
156 xenkbd_handle_key_event(info, &event->key);
157 break;
158
159 case XENKBD_TYPE_POS:
160 xenkbd_handle_position_event(info, &event->pos);
161 break;
162
163 case XENKBD_TYPE_MTOUCH:
164 xenkbd_handle_mt_event(info, &event->mtouch);
165 break;
166 }
167}
168
59static irqreturn_t input_handler(int rq, void *dev_id) 169static irqreturn_t input_handler(int rq, void *dev_id)
60{ 170{
61 struct xenkbd_info *info = dev_id; 171 struct xenkbd_info *info = dev_id;
@@ -66,44 +176,8 @@ static irqreturn_t input_handler(int rq, void *dev_id)
66 if (prod == page->in_cons) 176 if (prod == page->in_cons)
67 return IRQ_HANDLED; 177 return IRQ_HANDLED;
68 rmb(); /* ensure we see ring contents up to prod */ 178 rmb(); /* ensure we see ring contents up to prod */
69 for (cons = page->in_cons; cons != prod; cons++) { 179 for (cons = page->in_cons; cons != prod; cons++)
70 union xenkbd_in_event *event; 180 xenkbd_handle_event(info, &XENKBD_IN_RING_REF(page, cons));
71 struct input_dev *dev;
72 event = &XENKBD_IN_RING_REF(page, cons);
73
74 dev = info->ptr;
75 switch (event->type) {
76 case XENKBD_TYPE_MOTION:
77 input_report_rel(dev, REL_X, event->motion.rel_x);
78 input_report_rel(dev, REL_Y, event->motion.rel_y);
79 if (event->motion.rel_z)
80 input_report_rel(dev, REL_WHEEL,
81 -event->motion.rel_z);
82 break;
83 case XENKBD_TYPE_KEY:
84 dev = NULL;
85 if (test_bit(event->key.keycode, info->kbd->keybit))
86 dev = info->kbd;
87 if (test_bit(event->key.keycode, info->ptr->keybit))
88 dev = info->ptr;
89 if (dev)
90 input_report_key(dev, event->key.keycode,
91 event->key.pressed);
92 else
93 pr_warn("unhandled keycode 0x%x\n",
94 event->key.keycode);
95 break;
96 case XENKBD_TYPE_POS:
97 input_report_abs(dev, ABS_X, event->pos.abs_x);
98 input_report_abs(dev, ABS_Y, event->pos.abs_y);
99 if (event->pos.rel_z)
100 input_report_rel(dev, REL_WHEEL,
101 -event->pos.rel_z);
102 break;
103 }
104 if (dev)
105 input_sync(dev);
106 }
107 mb(); /* ensure we got ring contents */ 181 mb(); /* ensure we got ring contents */
108 page->in_cons = cons; 182 page->in_cons = cons;
109 notify_remote_via_irq(info->irq); 183 notify_remote_via_irq(info->irq);
@@ -115,9 +189,9 @@ static int xenkbd_probe(struct xenbus_device *dev,
115 const struct xenbus_device_id *id) 189 const struct xenbus_device_id *id)
116{ 190{
117 int ret, i; 191 int ret, i;
118 unsigned int abs; 192 unsigned int abs, touch;
119 struct xenkbd_info *info; 193 struct xenkbd_info *info;
120 struct input_dev *kbd, *ptr; 194 struct input_dev *kbd, *ptr, *mtouch;
121 195
122 info = kzalloc(sizeof(*info), GFP_KERNEL); 196 info = kzalloc(sizeof(*info), GFP_KERNEL);
123 if (!info) { 197 if (!info) {
@@ -152,6 +226,17 @@ static int xenkbd_probe(struct xenbus_device *dev,
152 } 226 }
153 } 227 }
154 228
229 touch = xenbus_read_unsigned(dev->nodename,
230 XENKBD_FIELD_FEAT_MTOUCH, 0);
231 if (touch) {
232 ret = xenbus_write(XBT_NIL, dev->nodename,
233 XENKBD_FIELD_REQ_MTOUCH, "1");
234 if (ret) {
235 pr_warn("xenkbd: can't request multi-touch");
236 touch = 0;
237 }
238 }
239
155 /* keyboard */ 240 /* keyboard */
156 kbd = input_allocate_device(); 241 kbd = input_allocate_device();
157 if (!kbd) 242 if (!kbd)
@@ -208,6 +293,58 @@ static int xenkbd_probe(struct xenbus_device *dev,
208 } 293 }
209 info->ptr = ptr; 294 info->ptr = ptr;
210 295
296 /* multi-touch device */
297 if (touch) {
298 int num_cont, width, height;
299
300 mtouch = input_allocate_device();
301 if (!mtouch)
302 goto error_nomem;
303
304 num_cont = xenbus_read_unsigned(info->xbdev->nodename,
305 XENKBD_FIELD_MT_NUM_CONTACTS,
306 1);
307 width = xenbus_read_unsigned(info->xbdev->nodename,
308 XENKBD_FIELD_MT_WIDTH,
309 XENFB_WIDTH);
310 height = xenbus_read_unsigned(info->xbdev->nodename,
311 XENKBD_FIELD_MT_HEIGHT,
312 XENFB_HEIGHT);
313
314 mtouch->name = "Xen Virtual Multi-touch";
315 mtouch->phys = info->phys;
316 mtouch->id.bustype = BUS_PCI;
317 mtouch->id.vendor = 0x5853;
318 mtouch->id.product = 0xfffd;
319
320 input_set_abs_params(mtouch, ABS_MT_TOUCH_MAJOR,
321 0, 255, 0, 0);
322 input_set_abs_params(mtouch, ABS_MT_POSITION_X,
323 0, width, 0, 0);
324 input_set_abs_params(mtouch, ABS_MT_POSITION_Y,
325 0, height, 0, 0);
326 input_set_abs_params(mtouch, ABS_MT_PRESSURE,
327 0, 255, 0, 0);
328
329 ret = input_mt_init_slots(mtouch, num_cont, INPUT_MT_DIRECT);
330 if (ret) {
331 input_free_device(mtouch);
332 xenbus_dev_fatal(info->xbdev, ret,
333 "input_mt_init_slots");
334 goto error;
335 }
336
337 ret = input_register_device(mtouch);
338 if (ret) {
339 input_free_device(mtouch);
340 xenbus_dev_fatal(info->xbdev, ret,
341 "input_register_device(mtouch)");
342 goto error;
343 }
344 info->mtouch_cur_contact_id = -1;
345 info->mtouch = mtouch;
346 }
347
211 ret = xenkbd_connect_backend(dev, info); 348 ret = xenkbd_connect_backend(dev, info);
212 if (ret < 0) 349 if (ret < 0)
213 goto error; 350 goto error;
@@ -240,6 +377,8 @@ static int xenkbd_remove(struct xenbus_device *dev)
240 input_unregister_device(info->kbd); 377 input_unregister_device(info->kbd);
241 if (info->ptr) 378 if (info->ptr)
242 input_unregister_device(info->ptr); 379 input_unregister_device(info->ptr);
380 if (info->mtouch)
381 input_unregister_device(info->mtouch);
243 free_page((unsigned long)info->page); 382 free_page((unsigned long)info->page);
244 kfree(info); 383 kfree(info);
245 return 0; 384 return 0;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c52da651269b..824f4c1c1f31 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -436,8 +436,10 @@ static int i8042_start(struct serio *serio)
436{ 436{
437 struct i8042_port *port = serio->port_data; 437 struct i8042_port *port = serio->port_data;
438 438
439 spin_lock_irq(&i8042_lock);
439 port->exists = true; 440 port->exists = true;
440 mb(); 441 spin_unlock_irq(&i8042_lock);
442
441 return 0; 443 return 0;
442} 444}
443 445
@@ -450,16 +452,20 @@ static void i8042_stop(struct serio *serio)
450{ 452{
451 struct i8042_port *port = serio->port_data; 453 struct i8042_port *port = serio->port_data;
452 454
455 spin_lock_irq(&i8042_lock);
453 port->exists = false; 456 port->exists = false;
457 port->serio = NULL;
458 spin_unlock_irq(&i8042_lock);
454 459
455 /* 460 /*
461 * We need to make sure that interrupt handler finishes using
462 * our serio port before we return from this function.
456 * We synchronize with both AUX and KBD IRQs because there is 463 * We synchronize with both AUX and KBD IRQs because there is
457 * a (very unlikely) chance that AUX IRQ is raised for KBD port 464 * a (very unlikely) chance that AUX IRQ is raised for KBD port
458 * and vice versa. 465 * and vice versa.
459 */ 466 */
460 synchronize_irq(I8042_AUX_IRQ); 467 synchronize_irq(I8042_AUX_IRQ);
461 synchronize_irq(I8042_KBD_IRQ); 468 synchronize_irq(I8042_KBD_IRQ);
462 port->serio = NULL;
463} 469}
464 470
465/* 471/*
@@ -576,7 +582,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
576 582
577 spin_unlock_irqrestore(&i8042_lock, flags); 583 spin_unlock_irqrestore(&i8042_lock, flags);
578 584
579 if (likely(port->exists && !filtered)) 585 if (likely(serio && !filtered))
580 serio_interrupt(serio, data, dfl); 586 serio_interrupt(serio, data, dfl);
581 587
582 out: 588 out: