{
        struct list_head *node;
 
-       list_for_each(node,&kbd_handler.h_list) {
+       list_for_each(node, &kbd_handler.h_list) {
                struct input_handle *handle = to_handle_h(node);
                if (test_bit(EV_SND, handle->dev->evbit)) {
                        if (test_bit(SND_TONE, handle->dev->sndbit))
-                               input_event(handle->dev, EV_SND, SND_TONE, 0);
+                               input_inject_event(handle, EV_SND, SND_TONE, 0);
                        if (test_bit(SND_BELL, handle->dev->sndbit))
-                               input_event(handle->dev, EV_SND, SND_BELL, 0);
+                               input_inject_event(handle, EV_SND, SND_BELL, 0);
                }
        }
 }
                        struct input_handle *handle = to_handle_h(node);
                        if (test_bit(EV_SND, handle->dev->evbit)) {
                                if (test_bit(SND_TONE, handle->dev->sndbit)) {
-                                       input_event(handle->dev, EV_SND, SND_TONE, hz);
+                                       input_inject_event(handle, EV_SND, SND_TONE, hz);
                                        break;
                                }
                                if (test_bit(SND_BELL, handle->dev->sndbit)) {
-                                       input_event(handle->dev, EV_SND, SND_BELL, 1);
+                                       input_inject_event(handle, EV_SND, SND_BELL, 1);
                                        break;
                                }
                        }
        unsigned int d = 0;
        unsigned int p = 0;
 
-       list_for_each(node,&kbd_handler.h_list) {
+       list_for_each(node, &kbd_handler.h_list) {
                struct input_handle *handle = to_handle_h(node);
                struct input_dev *dev = handle->dev;
 
                if (test_bit(EV_REP, dev->evbit)) {
                        if (rep->delay > 0)
-                               input_event(dev, EV_REP, REP_DELAY, rep->delay);
+                               input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
                        if (rep->period > 0)
-                               input_event(dev, EV_REP, REP_PERIOD, rep->period);
+                               input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
                        d = dev->rep[REP_DELAY];
                        p = dev->rep[REP_PERIOD];
                }
  * interrupt routines for this thing allows us to easily mask
  * this when we don't want any of the above to happen.
  * This allows for easy and efficient race-condition prevention
- * for kbd_start => input_event(dev, EV_LED, ...) => ...
+ * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
  */
 
 static void kbd_bh(unsigned long dummy)
 
        if (leds != ledstate) {
                list_for_each(node, &kbd_handler.h_list) {
-                       struct input_handle * handle = to_handle_h(node);
-                       input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-                       input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
-                       input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-                       input_sync(handle->dev);
+                       struct input_handle *handle = to_handle_h(node);
+                       input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+                       input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
+                       input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+                       input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
                }
        }
 
 
        tasklet_disable(&keyboard_tasklet);
        if (leds != 0xff) {
-               input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
-               input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
-               input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
-               input_sync(handle->dev);
+               input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+               input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
+               input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+               input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
        }
        tasklet_enable(&keyboard_tasklet);
 }
 
 
 static struct input_handler *input_table[8];
 
+/**
+ * input_event() - report new input event
+ * @handle: device that generated the event
+ * @type: type of the event
+ * @code: event code
+ * @value: value of the event
+ *
+ * This function should be used by drivers implementing various input devices
+ * See also input_inject_event()
+ */
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
        struct input_handle *handle;
 }
 EXPORT_SYMBOL(input_event);
 
+/**
+ * input_inject_event() - send input event from input handler
+ * @handle: input handle to send event through
+ * @type: type of the event
+ * @code: event code
+ * @value: value of the event
+ *
+ * Similar to input_event() but will ignore event if device is "grabbed" and handle
+ * injecting event is not the one that owns the device.
+ */
+void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+{
+       if (!handle->dev->grab || handle->dev->grab == handle)
+               input_event(handle->dev, type, code, value);
+}
+EXPORT_SYMBOL(input_inject_event);
+
 static void input_repeat_key(unsigned long data)
 {
        struct input_dev *dev = (void *) data;