Merge branch 'next' into for-linus
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 19 Mar 2011 06:38:50 +0000 (23:38 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 19 Mar 2011 06:38:50 +0000 (23:38 -0700)
14 files changed:
arch/arm/mach-tegra/include/mach/kbc.h
drivers/input/evdev.c
drivers/input/gameport/gameport.c
drivers/input/input.c
drivers/input/keyboard/tegra-kbc.c
drivers/input/misc/rotary_encoder.c
drivers/input/mouse/bcm5974.c
drivers/input/mouse/synaptics.h
drivers/input/serio/serio.c
drivers/input/tablet/wacom_sys.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/wacom_w8001.c
drivers/tty/sysrq.c
include/linux/input/matrix_keypad.h

index 66ad276..04c7798 100644 (file)
@@ -57,5 +57,6 @@ struct tegra_kbc_platform_data {
        const struct matrix_keymap_data *keymap_data;
 
        bool wakeup;
+       bool use_fn_map;
 };
 #endif
index c8471a2..7f42d3a 100644 (file)
@@ -321,6 +321,9 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
        struct input_event event;
        int retval;
 
+       if (count < input_event_size())
+               return -EINVAL;
+
        retval = mutex_lock_interruptible(&evdev->mutex);
        if (retval)
                return retval;
@@ -330,17 +333,16 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
                goto out;
        }
 
-       while (retval < count) {
-
+       do {
                if (input_event_from_user(buffer + retval, &event)) {
                        retval = -EFAULT;
                        goto out;
                }
+               retval += input_event_size();
 
                input_inject_event(&evdev->handle,
                                   event.type, event.code, event.value);
-               retval += input_event_size();
-       }
+       } while (retval + input_event_size() <= count);
 
  out:
        mutex_unlock(&evdev->mutex);
index 23cf8fc..5b8f59d 100644 (file)
@@ -360,7 +360,7 @@ static int gameport_queue_event(void *object, struct module *owner,
        event->owner = owner;
 
        list_add_tail(&event->node, &gameport_event_list);
-       schedule_work(&gameport_event_work);
+       queue_work(system_long_wq, &gameport_event_work);
 
 out:
        spin_unlock_irqrestore(&gameport_event_lock, flags);
index ee2959b..d6e8bd8 100644 (file)
@@ -75,7 +75,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
  * dev->event_lock held and interrupts disabled.
  */
 static void input_pass_event(struct input_dev *dev,
-                            struct input_handler *src_handler,
                             unsigned int type, unsigned int code, int value)
 {
        struct input_handler *handler;
@@ -94,15 +93,6 @@ static void input_pass_event(struct input_dev *dev,
                                continue;
 
                        handler = handle->handler;
-
-                       /*
-                        * If this is the handler that injected this
-                        * particular event we want to skip it to avoid
-                        * filters firing again and again.
-                        */
-                       if (handler == src_handler)
-                               continue;
-
                        if (!handler->filter) {
                                if (filtered)
                                        break;
@@ -132,7 +122,7 @@ static void input_repeat_key(unsigned long data)
        if (test_bit(dev->repeat_key, dev->key) &&
            is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
 
-               input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);
+               input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
 
                if (dev->sync) {
                        /*
@@ -141,7 +131,7 @@ static void input_repeat_key(unsigned long data)
                         * Otherwise assume that the driver will send
                         * SYN_REPORT once it's done.
                         */
-                       input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
                }
 
                if (dev->rep[REP_PERIOD])
@@ -174,7 +164,6 @@ static void input_stop_autorepeat(struct input_dev *dev)
 #define INPUT_PASS_TO_ALL      (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
 
 static int input_handle_abs_event(struct input_dev *dev,
-                                 struct input_handler *src_handler,
                                  unsigned int code, int *pval)
 {
        bool is_mt_event;
@@ -218,15 +207,13 @@ static int input_handle_abs_event(struct input_dev *dev,
        /* Flush pending "slot" event */
        if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
                input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
-               input_pass_event(dev, src_handler,
-                                EV_ABS, ABS_MT_SLOT, dev->slot);
+               input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
        }
 
        return INPUT_PASS_TO_HANDLERS;
 }
 
 static void input_handle_event(struct input_dev *dev,
-                              struct input_handler *src_handler,
                               unsigned int type, unsigned int code, int value)
 {
        int disposition = INPUT_IGNORE_EVENT;
@@ -279,8 +266,7 @@ static void input_handle_event(struct input_dev *dev,
 
        case EV_ABS:
                if (is_event_supported(code, dev->absbit, ABS_MAX))
-                       disposition = input_handle_abs_event(dev, src_handler,
-                                                            code, &value);
+                       disposition = input_handle_abs_event(dev, code, &value);
 
                break;
 
@@ -338,7 +324,7 @@ static void input_handle_event(struct input_dev *dev,
                dev->event(dev, type, code, value);
 
        if (disposition & INPUT_PASS_TO_HANDLERS)
-               input_pass_event(dev, src_handler, type, code, value);
+               input_pass_event(dev, type, code, value);
 }
 
 /**
@@ -367,7 +353,7 @@ void input_event(struct input_dev *dev,
 
                spin_lock_irqsave(&dev->event_lock, flags);
                add_input_randomness(type, code, value);
-               input_handle_event(dev, NULL, type, code, value);
+               input_handle_event(dev, type, code, value);
                spin_unlock_irqrestore(&dev->event_lock, flags);
        }
 }
@@ -397,8 +383,7 @@ void input_inject_event(struct input_handle *handle,
                rcu_read_lock();
                grab = rcu_dereference(dev->grab);
                if (!grab || grab == handle)
-                       input_handle_event(dev, handle->handler,
-                                          type, code, value);
+                       input_handle_event(dev, type, code, value);
                rcu_read_unlock();
 
                spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -611,10 +596,10 @@ static void input_dev_release_keys(struct input_dev *dev)
                for (code = 0; code <= KEY_MAX; code++) {
                        if (is_event_supported(code, dev->keybit, KEY_MAX) &&
                            __test_and_clear_bit(code, dev->key)) {
-                               input_pass_event(dev, NULL, EV_KEY, code, 0);
+                               input_pass_event(dev, EV_KEY, code, 0);
                        }
                }
-               input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
        }
 }
 
@@ -848,9 +833,9 @@ int input_set_keycode(struct input_dev *dev,
            !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
            __test_and_clear_bit(old_keycode, dev->key)) {
 
-               input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
+               input_pass_event(dev, EV_KEY, old_keycode, 0);
                if (dev->sync)
-                       input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
        }
 
  out:
index ac471b7..99ce903 100644 (file)
@@ -71,8 +71,9 @@ struct tegra_kbc {
        spinlock_t lock;
        unsigned int repoll_dly;
        unsigned long cp_dly_jiffies;
+       bool use_fn_map;
        const struct tegra_kbc_platform_data *pdata;
-       unsigned short keycode[KBC_MAX_KEY];
+       unsigned short keycode[KBC_MAX_KEY * 2];
        unsigned short current_keys[KBC_MAX_KPENT];
        unsigned int num_pressed_keys;
        struct timer_list timer;
@@ -178,6 +179,40 @@ static const u32 tegra_kbc_default_keymap[] = {
        KEY(15, 5, KEY_F2),
        KEY(15, 6, KEY_CAPSLOCK),
        KEY(15, 7, KEY_F6),
+
+       /* Software Handled Function Keys */
+       KEY(20, 0, KEY_KP7),
+
+       KEY(21, 0, KEY_KP9),
+       KEY(21, 1, KEY_KP8),
+       KEY(21, 2, KEY_KP4),
+       KEY(21, 4, KEY_KP1),
+
+       KEY(22, 1, KEY_KPSLASH),
+       KEY(22, 2, KEY_KP6),
+       KEY(22, 3, KEY_KP5),
+       KEY(22, 4, KEY_KP3),
+       KEY(22, 5, KEY_KP2),
+       KEY(22, 7, KEY_KP0),
+
+       KEY(27, 1, KEY_KPASTERISK),
+       KEY(27, 3, KEY_KPMINUS),
+       KEY(27, 4, KEY_KPPLUS),
+       KEY(27, 5, KEY_KPDOT),
+
+       KEY(28, 5, KEY_VOLUMEUP),
+
+       KEY(29, 3, KEY_HOME),
+       KEY(29, 4, KEY_END),
+       KEY(29, 5, KEY_BRIGHTNESSDOWN),
+       KEY(29, 6, KEY_VOLUMEDOWN),
+       KEY(29, 7, KEY_BRIGHTNESSUP),
+
+       KEY(30, 0, KEY_NUMLOCK),
+       KEY(30, 1, KEY_SCROLLLOCK),
+       KEY(30, 2, KEY_MUTE),
+
+       KEY(31, 4, KEY_HELP),
 };
 
 static const struct matrix_keymap_data tegra_kbc_default_keymap_data = {
@@ -224,6 +259,7 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
        unsigned int i;
        unsigned int num_down = 0;
        unsigned long flags;
+       bool fn_keypress = false;
 
        spin_lock_irqsave(&kbc->lock, flags);
        for (i = 0; i < KBC_MAX_KPENT; i++) {
@@ -237,11 +273,28 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
                                MATRIX_SCAN_CODE(row, col, KBC_ROW_SHIFT);
 
                        scancodes[num_down] = scancode;
-                       keycodes[num_down++] = kbc->keycode[scancode];
+                       keycodes[num_down] = kbc->keycode[scancode];
+                       /* If driver uses Fn map, do not report the Fn key. */
+                       if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map)
+                               fn_keypress = true;
+                       else
+                               num_down++;
                }
 
                val >>= 8;
        }
+
+       /*
+        * If the platform uses Fn keymaps, translate keys on a Fn keypress.
+        * Function keycodes are KBC_MAX_KEY apart from the plain keycodes.
+        */
+       if (fn_keypress) {
+               for (i = 0; i < num_down; i++) {
+                       scancodes[i] += KBC_MAX_KEY;
+                       keycodes[i] = kbc->keycode[scancodes[i]];
+               }
+       }
+
        spin_unlock_irqrestore(&kbc->lock, flags);
 
        tegra_kbc_report_released_keys(kbc->idev,
@@ -594,8 +647,11 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
 
        input_dev->keycode = kbc->keycode;
        input_dev->keycodesize = sizeof(kbc->keycode[0]);
-       input_dev->keycodemax = ARRAY_SIZE(kbc->keycode);
+       input_dev->keycodemax = KBC_MAX_KEY;
+       if (pdata->use_fn_map)
+               input_dev->keycodemax *= 2;
 
+       kbc->use_fn_map = pdata->use_fn_map;
        keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data;
        matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT,
                                   input_dev->keycode, input_dev->keybit);
index 1f8e010..7e64d01 100644 (file)
@@ -176,7 +176,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
 
        /* request the IRQs */
        err = request_irq(encoder->irq_a, &rotary_encoder_irq,
-                         IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+                         IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          DRV_NAME, encoder);
        if (err) {
                dev_err(&pdev->dev, "unable to request IRQ %d\n",
@@ -185,7 +185,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
        }
 
        err = request_irq(encoder->irq_b, &rotary_encoder_irq,
-                         IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+                         IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          DRV_NAME, encoder);
        if (err) {
                dev_err(&pdev->dev, "unable to request IRQ %d\n",
index 3185314..3aead91 100644 (file)
@@ -450,10 +450,6 @@ static int report_tp_state(struct bcm5974 *dev, int size)
                ptest = int2bound(&c->p, raw_p);
                origin = raw2int(f->origin);
 
-               /* set the integrated button if applicable */
-               if (c->tp_type == TYPE2)
-                       ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
-
                /* while tracking finger still valid, count all fingers */
                if (ptest > PRESSURE_LOW && origin) {
                        abs_p = ptest;
@@ -472,6 +468,10 @@ static int report_tp_state(struct bcm5974 *dev, int size)
                }
        }
 
+       /* set the integrated button if applicable */
+       if (c->tp_type == TYPE2)
+               ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
+
        if (dev->fingers < nmin)
                dev->fingers = nmin;
        if (dev->fingers > nmax)
index 25e5d04..7453938 100644 (file)
 #define SYN_EXT_CAP_REQUESTS(c)                (((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)    (((ec) & 0x00f000) >> 12)
 #define SYN_CAP_PRODUCT_ID(ec)         (((ec) & 0xff0000) >> 16)
+
+/*
+ * The following describes response for the 0x0c query.
+ *
+ * byte        mask    name                    meaning
+ * ----        ----    -------                 ------------
+ * 1   0x01    adjustable threshold    capacitive button sensitivity
+ *                                     can be adjusted
+ * 1   0x02    report max              query 0x0d gives max coord reported
+ * 1   0x04    clearpad                sensor is ClearPad product
+ * 1   0x08    advanced gesture        not particularly meaningful
+ * 1   0x10    clickpad bit 0          1-button ClickPad
+ * 1   0x60    multifinger mode        identifies firmware finger counting
+ *                                     (not reporting!) algorithm.
+ *                                     Not particularly meaningful
+ * 1   0x80    covered pad             W clipped to 14, 15 == pad mostly covered
+ * 2   0x01    clickpad bit 1          2-button ClickPad
+ * 2   0x02    deluxe LED controls     touchpad support LED commands
+ *                                     ala multimedia control bar
+ * 2   0x04    reduced filtering       firmware does less filtering on
+ *                                     position data, driver should watch
+ *                                     for noise.
+ */
 #define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100000) /* 1-button ClickPad */
 #define SYN_CAP_CLICKPAD2BTN(ex0c)     ((ex0c) & 0x000100) /* 2-button ClickPad */
 #define SYN_CAP_MAX_DIMENSIONS(ex0c)   ((ex0c) & 0x020000)
index db5b0bc..ba70058 100644 (file)
@@ -188,7 +188,8 @@ static void serio_free_event(struct serio_event *event)
        kfree(event);
 }
 
-static void serio_remove_duplicate_events(struct serio_event *event)
+static void serio_remove_duplicate_events(void *object,
+                                         enum serio_event_type type)
 {
        struct serio_event *e, *next;
        unsigned long flags;
@@ -196,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event)
        spin_lock_irqsave(&serio_event_lock, flags);
 
        list_for_each_entry_safe(e, next, &serio_event_list, node) {
-               if (event->object == e->object) {
+               if (object == e->object) {
                        /*
                         * If this event is of different type we should not
                         * look further - we only suppress duplicate events
                         * that were sent back-to-back.
                         */
-                       if (event->type != e->type)
+                       if (type != e->type)
                                break;
 
                        list_del_init(&e->node);
@@ -245,7 +246,7 @@ static void serio_handle_event(struct work_struct *work)
                        break;
                }
 
-               serio_remove_duplicate_events(event);
+               serio_remove_duplicate_events(event->object, event->type);
                serio_free_event(event);
        }
 
@@ -298,7 +299,7 @@ static int serio_queue_event(void *object, struct module *owner,
        event->owner = owner;
 
        list_add_tail(&event->node, &serio_event_list);
-       schedule_work(&serio_event_work);
+       queue_work(system_long_wq, &serio_event_work);
 
 out:
        spin_unlock_irqrestore(&serio_event_lock, flags);
@@ -436,10 +437,12 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
        } else if (!strncmp(buf, "rescan", count)) {
                serio_disconnect_port(serio);
                serio_find_driver(serio);
+               serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
        } else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
                serio_disconnect_port(serio);
                error = serio_bind_driver(serio, to_serio_driver(drv));
                put_driver(drv);
+               serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
        } else {
                error = -EINVAL;
        }
index b97665f..449c0a4 100644 (file)
@@ -519,7 +519,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        /* Retrieve the physical and logical size for OEM devices */
        error = wacom_retrieve_hid_descriptor(intf, features);
        if (error)
-               goto fail2;
+               goto fail3;
 
        wacom_setup_device_quirks(features);
 
index b31e90f..c24946f 100644 (file)
@@ -946,28 +946,29 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
        struct ads7846_platform_data *pdata = spi->dev.platform_data;
        int err;
 
-       /* REVISIT when the irq can be triggered active-low, or if for some
+       /*
+        * REVISIT when the irq can be triggered active-low, or if for some
         * reason the touchscreen isn't hooked up, we don't need to access
         * the pendown state.
         */
-       if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) {
-               dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
-               return -EINVAL;
-       }
 
        if (pdata->get_pendown_state) {
                ts->get_pendown_state = pdata->get_pendown_state;
-               return 0;
-       }
+       } else if (gpio_is_valid(pdata->gpio_pendown)) {
 
-       err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
-       if (err) {
-               dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
-                       pdata->gpio_pendown);
-               return err;
-       }
+               err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
+               if (err) {
+                       dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
+                               pdata->gpio_pendown);
+                       return err;
+               }
 
-       ts->gpio_pendown = pdata->gpio_pendown;
+               ts->gpio_pendown = pdata->gpio_pendown;
+
+       } else {
+               dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
+               return -EINVAL;
+       }
 
        return 0;
 }
@@ -1358,7 +1359,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
  err_put_regulator:
        regulator_put(ts->reg);
  err_free_gpio:
-       if (ts->gpio_pendown != -1)
+       if (!ts->get_pendown_state)
                gpio_free(ts->gpio_pendown);
  err_cleanup_filter:
        if (ts->filter_cleanup)
@@ -1388,8 +1389,13 @@ static int __devexit ads7846_remove(struct spi_device *spi)
        regulator_disable(ts->reg);
        regulator_put(ts->reg);
 
-       if (ts->gpio_pendown != -1)
+       if (!ts->get_pendown_state) {
+               /*
+                * If we are not using specialized pendown method we must
+                * have been relying on gpio we set up ourselves.
+                */
                gpio_free(ts->gpio_pendown);
+       }
 
        if (ts->filter_cleanup)
                ts->filter_cleanup(ts->filter_data);
index 5cb8449..c14412e 100644 (file)
@@ -51,6 +51,10 @@ MODULE_LICENSE("GPL");
 #define W8001_PKTLEN_TPCCTL    11      /* control packet */
 #define W8001_PKTLEN_TOUCH2FG  13
 
+/* resolution in points/mm */
+#define W8001_PEN_RESOLUTION    100
+#define W8001_TOUCH_RESOLUTION  10
+
 struct w8001_coord {
        u8 rdy;
        u8 tsw;
@@ -198,7 +202,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
                query->y = 1024;
                if (query->panel_res)
                        query->x = query->y = (1 << query->panel_res);
-               query->panel_res = 10;
+               query->panel_res = W8001_TOUCH_RESOLUTION;
        }
 }
 
@@ -394,6 +398,8 @@ static int w8001_setup(struct w8001 *w8001)
 
                input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
                input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
+               input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION);
+               input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION);
                input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
                if (coord.tilt_x && coord.tilt_y) {
                        input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
@@ -418,14 +424,17 @@ static int w8001_setup(struct w8001 *w8001)
                w8001->max_touch_x = touch.x;
                w8001->max_touch_y = touch.y;
 
-               /* scale to pen maximum */
                if (w8001->max_pen_x && w8001->max_pen_y) {
+                       /* if pen is supported scale to pen maximum */
                        touch.x = w8001->max_pen_x;
                        touch.y = w8001->max_pen_y;
+                       touch.panel_res = W8001_PEN_RESOLUTION;
                }
 
                input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
                input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
+               input_abs_set_res(dev, ABS_X, touch.panel_res);
+               input_abs_set_res(dev, ABS_Y, touch.panel_res);
 
                switch (touch.sensor_id) {
                case 0:
index 8e0dd25..81f1395 100644 (file)
@@ -571,6 +571,7 @@ struct sysrq_state {
        unsigned int alt_use;
        bool active;
        bool need_reinject;
+       bool reinjecting;
 };
 
 static void sysrq_reinject_alt_sysrq(struct work_struct *work)
@@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
        unsigned int alt_code = sysrq->alt_use;
 
        if (sysrq->need_reinject) {
+               /* we do not want the assignment to be reordered */
+               sysrq->reinjecting = true;
+               mb();
+
                /* Simulate press and release of Alt + SysRq */
                input_inject_event(handle, EV_KEY, alt_code, 1);
                input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
@@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
                input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
                input_inject_event(handle, EV_KEY, alt_code, 0);
                input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+               mb();
+               sysrq->reinjecting = false;
        }
 }
 
@@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_handle *handle,
        bool was_active = sysrq->active;
        bool suppress;
 
+       /*
+        * Do not filter anything if we are in the process of re-injecting
+        * Alt+SysRq combination.
+        */
+       if (sysrq->reinjecting)
+               return false;
+
        switch (type) {
 
        case EV_SYN:
@@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle,
                                sysrq->alt_use = sysrq->alt;
                                /*
                                 * If nothing else will be pressed we'll need
-                                * to re-inject Alt-SysRq keysroke.
+                                * to re-inject Alt-SysRq keysroke.
                                 */
                                sysrq->need_reinject = true;
                        }
index 6974746..fe7c4b9 100644 (file)
@@ -4,8 +4,8 @@
 #include <linux/types.h>
 #include <linux/input.h>
 
-#define MATRIX_MAX_ROWS                16
-#define MATRIX_MAX_COLS                16
+#define MATRIX_MAX_ROWS                32
+#define MATRIX_MAX_COLS                32
 
 #define KEY(row, col, val)     ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
                                 (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\