Commit 1f342790 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-2023112301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

 - revert of commit that caused regression to many Logitech unifying
   receiver users (Jiri Kosina)

 - power management fix for hid-mcp2221 (Hamish Martin)

 - fix for race condition between HID core and HID debug (Charles Yi)

 - a couple of assorted device-ID-specific quirks

* tag 'for-linus-2023112301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: multitouch: Add quirk for HONOR GLO-GXXX touchpad
  HID: hid-asus: reset the backlight brightness level on resume
  HID: hid-asus: add const to read-only outgoing usb buffer
  Revert "HID: logitech-dj: Add support for a new lightspeed receiver iteration"
  HID: add ALWAYS_POLL quirk for Apple kb
  HID: glorious: fix Glorious Model I HID report
  HID: fix HID device resource race between HID core and debugging support
  HID: apple: add Jamesdonkey and A3R to non-apple keyboards list
  HID: mcp2221: Allow IO to start during probe
  HID: mcp2221: Set driver data before I2C adapter add
parents d3fa86b1 9ffccb69
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -345,6 +345,8 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = {
	{ "AONE" },
	{ "GANSS" },
	{ "Hailuck" },
	{ "Jamesdonkey" },
	{ "A3R" },
};

static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
+23 −4
Original line number Diff line number Diff line
@@ -381,7 +381,7 @@ static int asus_raw_event(struct hid_device *hdev,
	return 0;
}

static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size)
static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size)
{
	unsigned char *dmabuf;
	int ret;
@@ -404,7 +404,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size

static int asus_kbd_init(struct hid_device *hdev)
{
	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
	const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
		     0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
	int ret;

@@ -418,7 +418,7 @@ static int asus_kbd_init(struct hid_device *hdev)
static int asus_kbd_get_functions(struct hid_device *hdev,
				  unsigned char *kbd_func)
{
	u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
	const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 };
	u8 *readbuf;
	int ret;

@@ -449,7 +449,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev,

static int rog_nkey_led_init(struct hid_device *hdev)
{
	u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
	const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 };
	u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20,
				0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
	u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1,
@@ -1000,6 +1000,24 @@ static int asus_start_multitouch(struct hid_device *hdev)
	return 0;
}

static int __maybe_unused asus_resume(struct hid_device *hdev) {
	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
	int ret = 0;

	if (drvdata->kbd_backlight) {
		const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4,
				drvdata->kbd_backlight->cdev.brightness };
		ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
		if (ret < 0) {
			hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
			goto asus_resume_err;
		}
	}

asus_resume_err:
	return ret;
}

static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
{
	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
@@ -1294,6 +1312,7 @@ static struct hid_driver asus_driver = {
	.input_configured       = asus_input_configured,
#ifdef CONFIG_PM
	.reset_resume           = asus_reset_resume,
	.resume					= asus_resume,
#endif
	.event			= asus_event,
	.raw_event		= asus_raw_event
+10 −2
Original line number Diff line number Diff line
@@ -702,15 +702,22 @@ static void hid_close_report(struct hid_device *device)
 * Free a device structure, all reports, and all fields.
 */

static void hid_device_release(struct device *dev)
void hiddev_free(struct kref *ref)
{
	struct hid_device *hid = to_hid_device(dev);
	struct hid_device *hid = container_of(ref, struct hid_device, ref);

	hid_close_report(hid);
	kfree(hid->dev_rdesc);
	kfree(hid);
}

static void hid_device_release(struct device *dev)
{
	struct hid_device *hid = to_hid_device(dev);

	kref_put(&hid->ref, hiddev_free);
}

/*
 * Fetch a report description item from the data stream. We support long
 * items, though they are not used yet.
@@ -2846,6 +2853,7 @@ struct hid_device *hid_allocate_device(void)
	spin_lock_init(&hdev->debug_list_lock);
	sema_init(&hdev->driver_input_lock, 1);
	mutex_init(&hdev->ll_open_lock);
	kref_init(&hdev->ref);

	hid_bpf_device_init(hdev);

+3 −0
Original line number Diff line number Diff line
@@ -1135,6 +1135,7 @@ static int hid_debug_events_open(struct inode *inode, struct file *file)
		goto out;
	}
	list->hdev = (struct hid_device *) inode->i_private;
	kref_get(&list->hdev->ref);
	file->private_data = list;
	mutex_init(&list->read_mutex);

@@ -1227,6 +1228,8 @@ static int hid_debug_events_release(struct inode *inode, struct file *file)
	list_del(&list->node);
	spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags);
	kfifo_free(&list->hid_debug_fifo);

	kref_put(&list->hdev->ref, hiddev_free);
	kfree(list);

	return 0;
+14 −2
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice");
 * Glorious Model O and O- specify the const flag in the consumer input
 * report descriptor, which leads to inputs being ignored. Fix this
 * by patching the descriptor.
 *
 * Glorious Model I incorrectly specifes the Usage Minimum for its
 * keyboard HID report, causing keycodes to be misinterpreted.
 * Fix this by setting Usage Minimum to 0 in that report.
 */
static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
@@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		rdesc[85] = rdesc[113] = rdesc[141] = \
			HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE;
	}
	if (*rsize == 156 && rdesc[41] == 1) {
		hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n");
		rdesc[41] = 0;
	}
	return rdesc;
}

@@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev)
		model = "Model O"; break;
	case USB_DEVICE_ID_GLORIOUS_MODEL_D:
		model = "Model D"; break;
	case USB_DEVICE_ID_GLORIOUS_MODEL_I:
		model = "Model I"; break;
	}

	snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model);
@@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev,
}

static const struct hid_device_id glorious_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS,
	{ HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,
		USB_DEVICE_ID_GLORIOUS_MODEL_O) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS,
	{ HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH,
		USB_DEVICE_ID_GLORIOUS_MODEL_D) },
	{ HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW,
		USB_DEVICE_ID_GLORIOUS_MODEL_I) },
	{ }
};
MODULE_DEVICE_TABLE(hid, glorious_devices);
Loading