Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull a few more input updates from Dmitry Torokhov:

- multi-touch handling for Xen

- fix for long-standing bug causing crashes in i8042 on boot

- change to gpio_keys to better handle key presses during system state
transition

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: i8042 - fix crash at boot time
Input: gpio_keys - handle the missing key press event in resume phase
Input: xen-kbdfront - add multi-touch support

+204 -44
+16 -1
drivers/input/keyboard/gpio_keys.c
··· 48 48 spinlock_t lock; 49 49 bool disabled; 50 50 bool key_pressed; 51 + bool suspended; 51 52 }; 52 53 53 54 struct gpio_keys_drvdata { ··· 397 396 398 397 BUG_ON(irq != bdata->irq); 399 398 400 - if (bdata->button->wakeup) 399 + if (bdata->button->wakeup) { 400 + const struct gpio_keys_button *button = bdata->button; 401 + 401 402 pm_stay_awake(bdata->input->dev.parent); 403 + if (bdata->suspended && 404 + (button->type == 0 || button->type == EV_KEY)) { 405 + /* 406 + * Simulate wakeup key press in case the key has 407 + * already released by the time we got interrupt 408 + * handler to run. 409 + */ 410 + input_report_key(bdata->input, button->code, 1); 411 + } 412 + } 402 413 403 414 mod_delayed_work(system_wq, 404 415 &bdata->work, ··· 868 855 struct gpio_button_data *bdata = &ddata->data[i]; 869 856 if (bdata->button->wakeup) 870 857 enable_irq_wake(bdata->irq); 858 + bdata->suspended = true; 871 859 } 872 860 } else { 873 861 mutex_lock(&input->mutex); ··· 892 878 struct gpio_button_data *bdata = &ddata->data[i]; 893 879 if (bdata->button->wakeup) 894 880 disable_irq_wake(bdata->irq); 881 + bdata->suspended = false; 895 882 } 896 883 } else { 897 884 mutex_lock(&input->mutex);
+179 -40
drivers/input/misc/xen-kbdfront.c
··· 17 17 #include <linux/errno.h> 18 18 #include <linux/module.h> 19 19 #include <linux/input.h> 20 + #include <linux/input/mt.h> 20 21 #include <linux/slab.h> 21 22 22 23 #include <asm/xen/hypervisor.h> ··· 35 34 struct xenkbd_info { 36 35 struct input_dev *kbd; 37 36 struct input_dev *ptr; 37 + struct input_dev *mtouch; 38 38 struct xenkbd_page *page; 39 39 int gref; 40 40 int irq; 41 41 struct xenbus_device *xbdev; 42 42 char phys[32]; 43 + /* current MT slot/contact ID we are injecting events in */ 44 + int mtouch_cur_contact_id; 43 45 }; 44 46 45 47 enum { KPARAM_X, KPARAM_Y, KPARAM_CNT }; ··· 60 56 * to do that. 61 57 */ 62 58 59 + static void xenkbd_handle_motion_event(struct xenkbd_info *info, 60 + struct xenkbd_motion *motion) 61 + { 62 + input_report_rel(info->ptr, REL_X, motion->rel_x); 63 + input_report_rel(info->ptr, REL_Y, motion->rel_y); 64 + if (motion->rel_z) 65 + input_report_rel(info->ptr, REL_WHEEL, -motion->rel_z); 66 + input_sync(info->ptr); 67 + } 68 + 69 + static void xenkbd_handle_position_event(struct xenkbd_info *info, 70 + struct xenkbd_position *pos) 71 + { 72 + input_report_abs(info->ptr, ABS_X, pos->abs_x); 73 + input_report_abs(info->ptr, ABS_Y, pos->abs_y); 74 + if (pos->rel_z) 75 + input_report_rel(info->ptr, REL_WHEEL, -pos->rel_z); 76 + input_sync(info->ptr); 77 + } 78 + 79 + static void xenkbd_handle_key_event(struct xenkbd_info *info, 80 + struct xenkbd_key *key) 81 + { 82 + struct input_dev *dev; 83 + 84 + if (test_bit(key->keycode, info->ptr->keybit)) { 85 + dev = info->ptr; 86 + } else if (test_bit(key->keycode, info->kbd->keybit)) { 87 + dev = info->kbd; 88 + } else { 89 + pr_warn("unhandled keycode 0x%x\n", key->keycode); 90 + return; 91 + } 92 + 93 + input_report_key(dev, key->keycode, key->pressed); 94 + input_sync(dev); 95 + } 96 + 97 + static void xenkbd_handle_mt_event(struct xenkbd_info *info, 98 + struct xenkbd_mtouch *mtouch) 99 + { 100 + if (unlikely(!info->mtouch)) 101 + return; 102 + 103 + if (mtouch->contact_id != info->mtouch_cur_contact_id) { 104 + info->mtouch_cur_contact_id = mtouch->contact_id; 105 + input_mt_slot(info->mtouch, mtouch->contact_id); 106 + } 107 + 108 + switch (mtouch->event_type) { 109 + case XENKBD_MT_EV_DOWN: 110 + input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, true); 111 + /* fall through */ 112 + 113 + case XENKBD_MT_EV_MOTION: 114 + input_report_abs(info->mtouch, ABS_MT_POSITION_X, 115 + mtouch->u.pos.abs_x); 116 + input_report_abs(info->mtouch, ABS_MT_POSITION_Y, 117 + mtouch->u.pos.abs_y); 118 + break; 119 + 120 + case XENKBD_MT_EV_SHAPE: 121 + input_report_abs(info->mtouch, ABS_MT_TOUCH_MAJOR, 122 + mtouch->u.shape.major); 123 + input_report_abs(info->mtouch, ABS_MT_TOUCH_MINOR, 124 + mtouch->u.shape.minor); 125 + break; 126 + 127 + case XENKBD_MT_EV_ORIENT: 128 + input_report_abs(info->mtouch, ABS_MT_ORIENTATION, 129 + mtouch->u.orientation); 130 + break; 131 + 132 + case XENKBD_MT_EV_UP: 133 + input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false); 134 + break; 135 + 136 + case XENKBD_MT_EV_SYN: 137 + input_mt_sync_frame(info->mtouch); 138 + input_sync(info->mtouch); 139 + break; 140 + } 141 + } 142 + 143 + static void xenkbd_handle_event(struct xenkbd_info *info, 144 + union xenkbd_in_event *event) 145 + { 146 + switch (event->type) { 147 + case XENKBD_TYPE_MOTION: 148 + xenkbd_handle_motion_event(info, &event->motion); 149 + break; 150 + 151 + case XENKBD_TYPE_KEY: 152 + xenkbd_handle_key_event(info, &event->key); 153 + break; 154 + 155 + case XENKBD_TYPE_POS: 156 + xenkbd_handle_position_event(info, &event->pos); 157 + break; 158 + 159 + case XENKBD_TYPE_MTOUCH: 160 + xenkbd_handle_mt_event(info, &event->mtouch); 161 + break; 162 + } 163 + } 164 + 63 165 static irqreturn_t input_handler(int rq, void *dev_id) 64 166 { 65 167 struct xenkbd_info *info = dev_id; ··· 176 66 if (prod == page->in_cons) 177 67 return IRQ_HANDLED; 178 68 rmb(); /* ensure we see ring contents up to prod */ 179 - for (cons = page->in_cons; cons != prod; cons++) { 180 - union xenkbd_in_event *event; 181 - struct input_dev *dev; 182 - event = &XENKBD_IN_RING_REF(page, cons); 183 - 184 - dev = info->ptr; 185 - switch (event->type) { 186 - case XENKBD_TYPE_MOTION: 187 - input_report_rel(dev, REL_X, event->motion.rel_x); 188 - input_report_rel(dev, REL_Y, event->motion.rel_y); 189 - if (event->motion.rel_z) 190 - input_report_rel(dev, REL_WHEEL, 191 - -event->motion.rel_z); 192 - break; 193 - case XENKBD_TYPE_KEY: 194 - dev = NULL; 195 - if (test_bit(event->key.keycode, info->kbd->keybit)) 196 - dev = info->kbd; 197 - if (test_bit(event->key.keycode, info->ptr->keybit)) 198 - dev = info->ptr; 199 - if (dev) 200 - input_report_key(dev, event->key.keycode, 201 - event->key.pressed); 202 - else 203 - pr_warn("unhandled keycode 0x%x\n", 204 - event->key.keycode); 205 - break; 206 - case XENKBD_TYPE_POS: 207 - input_report_abs(dev, ABS_X, event->pos.abs_x); 208 - input_report_abs(dev, ABS_Y, event->pos.abs_y); 209 - if (event->pos.rel_z) 210 - input_report_rel(dev, REL_WHEEL, 211 - -event->pos.rel_z); 212 - break; 213 - } 214 - if (dev) 215 - input_sync(dev); 216 - } 69 + for (cons = page->in_cons; cons != prod; cons++) 70 + xenkbd_handle_event(info, &XENKBD_IN_RING_REF(page, cons)); 217 71 mb(); /* ensure we got ring contents */ 218 72 page->in_cons = cons; 219 73 notify_remote_via_irq(info->irq); ··· 189 115 const struct xenbus_device_id *id) 190 116 { 191 117 int ret, i; 192 - unsigned int abs; 118 + unsigned int abs, touch; 193 119 struct xenkbd_info *info; 194 - struct input_dev *kbd, *ptr; 120 + struct input_dev *kbd, *ptr, *mtouch; 195 121 196 122 info = kzalloc(sizeof(*info), GFP_KERNEL); 197 123 if (!info) { ··· 223 149 if (ret) { 224 150 pr_warn("xenkbd: can't request abs-pointer\n"); 225 151 abs = 0; 152 + } 153 + } 154 + 155 + touch = xenbus_read_unsigned(dev->nodename, 156 + XENKBD_FIELD_FEAT_MTOUCH, 0); 157 + if (touch) { 158 + ret = xenbus_write(XBT_NIL, dev->nodename, 159 + XENKBD_FIELD_REQ_MTOUCH, "1"); 160 + if (ret) { 161 + pr_warn("xenkbd: can't request multi-touch"); 162 + touch = 0; 226 163 } 227 164 } 228 165 ··· 293 208 } 294 209 info->ptr = ptr; 295 210 211 + /* multi-touch device */ 212 + if (touch) { 213 + int num_cont, width, height; 214 + 215 + mtouch = input_allocate_device(); 216 + if (!mtouch) 217 + goto error_nomem; 218 + 219 + num_cont = xenbus_read_unsigned(info->xbdev->nodename, 220 + XENKBD_FIELD_MT_NUM_CONTACTS, 221 + 1); 222 + width = xenbus_read_unsigned(info->xbdev->nodename, 223 + XENKBD_FIELD_MT_WIDTH, 224 + XENFB_WIDTH); 225 + height = xenbus_read_unsigned(info->xbdev->nodename, 226 + XENKBD_FIELD_MT_HEIGHT, 227 + XENFB_HEIGHT); 228 + 229 + mtouch->name = "Xen Virtual Multi-touch"; 230 + mtouch->phys = info->phys; 231 + mtouch->id.bustype = BUS_PCI; 232 + mtouch->id.vendor = 0x5853; 233 + mtouch->id.product = 0xfffd; 234 + 235 + input_set_abs_params(mtouch, ABS_MT_TOUCH_MAJOR, 236 + 0, 255, 0, 0); 237 + input_set_abs_params(mtouch, ABS_MT_POSITION_X, 238 + 0, width, 0, 0); 239 + input_set_abs_params(mtouch, ABS_MT_POSITION_Y, 240 + 0, height, 0, 0); 241 + input_set_abs_params(mtouch, ABS_MT_PRESSURE, 242 + 0, 255, 0, 0); 243 + 244 + ret = input_mt_init_slots(mtouch, num_cont, INPUT_MT_DIRECT); 245 + if (ret) { 246 + input_free_device(mtouch); 247 + xenbus_dev_fatal(info->xbdev, ret, 248 + "input_mt_init_slots"); 249 + goto error; 250 + } 251 + 252 + ret = input_register_device(mtouch); 253 + if (ret) { 254 + input_free_device(mtouch); 255 + xenbus_dev_fatal(info->xbdev, ret, 256 + "input_register_device(mtouch)"); 257 + goto error; 258 + } 259 + info->mtouch_cur_contact_id = -1; 260 + info->mtouch = mtouch; 261 + } 262 + 296 263 ret = xenkbd_connect_backend(dev, info); 297 264 if (ret < 0) 298 265 goto error; ··· 377 240 input_unregister_device(info->kbd); 378 241 if (info->ptr) 379 242 input_unregister_device(info->ptr); 243 + if (info->mtouch) 244 + input_unregister_device(info->mtouch); 380 245 free_page((unsigned long)info->page); 381 246 kfree(info); 382 247 return 0;
+9 -3
drivers/input/serio/i8042.c
··· 436 436 { 437 437 struct i8042_port *port = serio->port_data; 438 438 439 + spin_lock_irq(&i8042_lock); 439 440 port->exists = true; 440 - mb(); 441 + spin_unlock_irq(&i8042_lock); 442 + 441 443 return 0; 442 444 } 443 445 ··· 452 450 { 453 451 struct i8042_port *port = serio->port_data; 454 452 453 + spin_lock_irq(&i8042_lock); 455 454 port->exists = false; 455 + port->serio = NULL; 456 + spin_unlock_irq(&i8042_lock); 456 457 457 458 /* 459 + * We need to make sure that interrupt handler finishes using 460 + * our serio port before we return from this function. 458 461 * We synchronize with both AUX and KBD IRQs because there is 459 462 * a (very unlikely) chance that AUX IRQ is raised for KBD port 460 463 * and vice versa. 461 464 */ 462 465 synchronize_irq(I8042_AUX_IRQ); 463 466 synchronize_irq(I8042_KBD_IRQ); 464 - port->serio = NULL; 465 467 } 466 468 467 469 /* ··· 582 576 583 577 spin_unlock_irqrestore(&i8042_lock, flags); 584 578 585 - if (likely(port->exists && !filtered)) 579 + if (likely(serio && !filtered)) 586 580 serio_interrupt(serio, data, dfl); 587 581 588 582 out: