aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/usbhid/hid-core.c26
-rw-r--r--include/linux/hid.h1
2 files changed, 24 insertions, 3 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 79cf503e37bf..ddd547ad6d7e 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -82,7 +82,7 @@ static int hid_start_in(struct hid_device *hid)
82 struct usbhid_device *usbhid = hid->driver_data; 82 struct usbhid_device *usbhid = hid->driver_data;
83 83
84 spin_lock_irqsave(&usbhid->lock, flags); 84 spin_lock_irqsave(&usbhid->lock, flags);
85 if (hid->open > 0 && 85 if ((hid->open > 0 || hid->quirks & HID_QUIRK_ALWAYS_POLL) &&
86 !test_bit(HID_DISCONNECTED, &usbhid->iofl) && 86 !test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
87 !test_bit(HID_SUSPENDED, &usbhid->iofl) && 87 !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
88 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { 88 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
@@ -292,6 +292,8 @@ static void hid_irq_in(struct urb *urb)
292 case 0: /* success */ 292 case 0: /* success */
293 usbhid_mark_busy(usbhid); 293 usbhid_mark_busy(usbhid);
294 usbhid->retry_delay = 0; 294 usbhid->retry_delay = 0;
295 if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open)
296 break;
295 hid_input_report(urb->context, HID_INPUT_REPORT, 297 hid_input_report(urb->context, HID_INPUT_REPORT,
296 urb->transfer_buffer, 298 urb->transfer_buffer,
297 urb->actual_length, 1); 299 urb->actual_length, 1);
@@ -735,8 +737,10 @@ void usbhid_close(struct hid_device *hid)
735 if (!--hid->open) { 737 if (!--hid->open) {
736 spin_unlock_irq(&usbhid->lock); 738 spin_unlock_irq(&usbhid->lock);
737 hid_cancel_delayed_stuff(usbhid); 739 hid_cancel_delayed_stuff(usbhid);
738 usb_kill_urb(usbhid->urbin); 740 if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
739 usbhid->intf->needs_remote_wakeup = 0; 741 usb_kill_urb(usbhid->urbin);
742 usbhid->intf->needs_remote_wakeup = 0;
743 }
740 } else { 744 } else {
741 spin_unlock_irq(&usbhid->lock); 745 spin_unlock_irq(&usbhid->lock);
742 } 746 }
@@ -1134,6 +1138,19 @@ static int usbhid_start(struct hid_device *hid)
1134 1138
1135 set_bit(HID_STARTED, &usbhid->iofl); 1139 set_bit(HID_STARTED, &usbhid->iofl);
1136 1140
1141 if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
1142 ret = usb_autopm_get_interface(usbhid->intf);
1143 if (ret)
1144 goto fail;
1145 usbhid->intf->needs_remote_wakeup = 1;
1146 ret = hid_start_in(hid);
1147 if (ret) {
1148 dev_err(&hid->dev,
1149 "failed to start in urb: %d\n", ret);
1150 }
1151 usb_autopm_put_interface(usbhid->intf);
1152 }
1153
1137 /* Some keyboards don't work until their LEDs have been set. 1154 /* Some keyboards don't work until their LEDs have been set.
1138 * Since BIOSes do set the LEDs, it must be safe for any device 1155 * Since BIOSes do set the LEDs, it must be safe for any device
1139 * that supports the keyboard boot protocol. 1156 * that supports the keyboard boot protocol.
@@ -1166,6 +1183,9 @@ static void usbhid_stop(struct hid_device *hid)
1166 if (WARN_ON(!usbhid)) 1183 if (WARN_ON(!usbhid))
1167 return; 1184 return;
1168 1185
1186 if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
1187 usbhid->intf->needs_remote_wakeup = 0;
1188
1169 clear_bit(HID_STARTED, &usbhid->iofl); 1189 clear_bit(HID_STARTED, &usbhid->iofl);
1170 spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */ 1190 spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
1171 set_bit(HID_DISCONNECTED, &usbhid->iofl); 1191 set_bit(HID_DISCONNECTED, &usbhid->iofl);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index f53c4a9cca1d..26ee25fced27 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -287,6 +287,7 @@ struct hid_item {
287#define HID_QUIRK_HIDINPUT_FORCE 0x00000080 287#define HID_QUIRK_HIDINPUT_FORCE 0x00000080
288#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 288#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
289#define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200 289#define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200
290#define HID_QUIRK_ALWAYS_POLL 0x00000400
290#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 291#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
291#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000 292#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000
292#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000 293#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000