Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9d0683e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull HID fixes from Jiri Kosina:

 - regression fix (missing IRQs) for devices that require 'always poll'
   quirk, from Dmitry Torokhov

 - new device ID addition to Ortek driver, from Benjamin Tissoires

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: ortek: add one more buggy device
  HID: usbhid: fix "always poll" quirk
parents eeb7c41d c228352d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2216,6 +2216,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
#if IS_ENABLED(CONFIG_HID_ORTEK)
	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
#endif
#if IS_ENABLED(CONFIG_HID_PANTHERLORD)
+1 −0
Original line number Diff line number Diff line
@@ -824,6 +824,7 @@
#define USB_VENDOR_ID_ORTEK		0x05a4
#define USB_DEVICE_ID_ORTEK_PKB1700	0x1700
#define USB_DEVICE_ID_ORTEK_WKB2000	0x2000
#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S	0x8003

#define USB_VENDOR_ID_PLANTRONICS	0x047f

+4 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 *
 *    Ortek PKB-1700
 *    Ortek WKB-2000
 *    iHome IMAC-A210S
 *    Skycable wireless presenter
 *
 *  Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com>
@@ -28,10 +29,10 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
		hid_info(hdev, "Fixing up logical minimum in report descriptor (Ortek)\n");
		hid_info(hdev, "Fixing up logical maximum in report descriptor (Ortek)\n");
		rdesc[55] = 0x92;
	} else if (*rsize >= 54 && rdesc[52] == 0x25 && rdesc[53] == 0x01) {
		hid_info(hdev, "Fixing up logical minimum in report descriptor (Skycable)\n");
		hid_info(hdev, "Fixing up logical maximum in report descriptor (Skycable)\n");
		rdesc[53] = 0x65;
	}
	return rdesc;
@@ -40,6 +41,7 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static const struct hid_device_id ortek_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
	{ }
};
+10 −6
Original line number Diff line number Diff line
@@ -680,18 +680,21 @@ static int usbhid_open(struct hid_device *hid)
	struct usbhid_device *usbhid = hid->driver_data;
	int res;

	set_bit(HID_OPENED, &usbhid->iofl);

	if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
		return 0;

	res = usb_autopm_get_interface(usbhid->intf);
	/* the device must be awake to reliably request remote wakeup */
	if (res < 0)
	if (res < 0) {
		clear_bit(HID_OPENED, &usbhid->iofl);
		return -EIO;
	}

	usbhid->intf->needs_remote_wakeup = 1;

	set_bit(HID_RESUME_RUNNING, &usbhid->iofl);
	set_bit(HID_OPENED, &usbhid->iofl);
	set_bit(HID_IN_POLLING, &usbhid->iofl);

	res = hid_start_in(hid);
@@ -727,19 +730,20 @@ static void usbhid_close(struct hid_device *hid)
{
	struct usbhid_device *usbhid = hid->driver_data;

	if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
		return;

	/*
	 * Make sure we don't restart data acquisition due to
	 * a resumption we no longer care about by avoiding racing
	 * with hid_start_in().
	 */
	spin_lock_irq(&usbhid->lock);
	clear_bit(HID_IN_POLLING, &usbhid->iofl);
	clear_bit(HID_OPENED, &usbhid->iofl);
	if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL))
		clear_bit(HID_IN_POLLING, &usbhid->iofl);
	spin_unlock_irq(&usbhid->lock);

	if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
		return;

	hid_cancel_delayed_stuff(usbhid);
	usb_kill_urb(usbhid->urbin);
	usbhid->intf->needs_remote_wakeup = 0;