diff options
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 36 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 1 |
2 files changed, 25 insertions, 12 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index ca6849a0121e..04e34b917045 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -278,18 +278,20 @@ static void hid_irq_in(struct urb *urb) | |||
278 | usbhid->retry_delay = 0; | 278 | usbhid->retry_delay = 0; |
279 | if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) | 279 | if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open) |
280 | break; | 280 | break; |
281 | hid_input_report(urb->context, HID_INPUT_REPORT, | 281 | if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { |
282 | urb->transfer_buffer, | 282 | hid_input_report(urb->context, HID_INPUT_REPORT, |
283 | urb->actual_length, 1); | 283 | urb->transfer_buffer, |
284 | /* | 284 | urb->actual_length, 1); |
285 | * autosuspend refused while keys are pressed | 285 | /* |
286 | * because most keyboards don't wake up when | 286 | * autosuspend refused while keys are pressed |
287 | * a key is released | 287 | * because most keyboards don't wake up when |
288 | */ | 288 | * a key is released |
289 | if (hid_check_keys_pressed(hid)) | 289 | */ |
290 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); | 290 | if (hid_check_keys_pressed(hid)) |
291 | else | 291 | set_bit(HID_KEYS_PRESSED, &usbhid->iofl); |
292 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); | 292 | else |
293 | clear_bit(HID_KEYS_PRESSED, &usbhid->iofl); | ||
294 | } | ||
293 | break; | 295 | break; |
294 | case -EPIPE: /* stall */ | 296 | case -EPIPE: /* stall */ |
295 | usbhid_mark_busy(usbhid); | 297 | usbhid_mark_busy(usbhid); |
@@ -688,6 +690,7 @@ int usbhid_open(struct hid_device *hid) | |||
688 | goto done; | 690 | goto done; |
689 | } | 691 | } |
690 | usbhid->intf->needs_remote_wakeup = 1; | 692 | usbhid->intf->needs_remote_wakeup = 1; |
693 | set_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
691 | res = hid_start_in(hid); | 694 | res = hid_start_in(hid); |
692 | if (res) { | 695 | if (res) { |
693 | if (res != -ENOSPC) { | 696 | if (res != -ENOSPC) { |
@@ -701,6 +704,15 @@ int usbhid_open(struct hid_device *hid) | |||
701 | } | 704 | } |
702 | } | 705 | } |
703 | usb_autopm_put_interface(usbhid->intf); | 706 | usb_autopm_put_interface(usbhid->intf); |
707 | |||
708 | /* | ||
709 | * In case events are generated while nobody was listening, | ||
710 | * some are released when the device is re-opened. | ||
711 | * Wait 50 msec for the queue to empty before allowing events | ||
712 | * to go through hid. | ||
713 | */ | ||
714 | msleep(50); | ||
715 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
704 | } | 716 | } |
705 | done: | 717 | done: |
706 | mutex_unlock(&hid_open_mut); | 718 | mutex_unlock(&hid_open_mut); |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index f633c24ce28b..807922b49aa4 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -52,6 +52,7 @@ struct usb_interface *usbhid_find_interface(int minor); | |||
52 | #define HID_STARTED 8 | 52 | #define HID_STARTED 8 |
53 | #define HID_KEYS_PRESSED 10 | 53 | #define HID_KEYS_PRESSED 10 |
54 | #define HID_NO_BANDWIDTH 11 | 54 | #define HID_NO_BANDWIDTH 11 |
55 | #define HID_RESUME_RUNNING 12 | ||
55 | 56 | ||
56 | /* | 57 | /* |
57 | * USB-specific HID struct, to be pointed to | 58 | * USB-specific HID struct, to be pointed to |