Merge tag 'for-linus-2023112301' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Nov 2023 01:31:53 +0000 (17:31 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Nov 2023 01:31:53 +0000 (17:31 -0800)
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

drivers/hid/hid-apple.c
drivers/hid/hid-asus.c
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-glorious.c
drivers/hid/hid-ids.h
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-mcp2221.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-quirks.c
include/linux/hid.h

index 3ca45975c686eee3563dabb287caf4c1c21a10ac..d9e9829b22001aa468c1fd837fc692ce807d313f 100644 (file)
@@ -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)
index fd61dba882338e022685fca453e2d70a0e093106..78cdfb8b9a7aeb6f03b6dc58157cb0b925b4ac76 100644 (file)
@@ -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
index 8992e3c1e7698eeaeeb7711876d66022ef5ec9d0..e0181218ad857862aba07f6ff0ffe30df42bfb16 100644 (file)
@@ -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);
 
index e7ef1ea107c9e618b035552ebf45154ff43a30df..7dd83ec74f8a9df75c6e966b3876f8481166a22f 100644 (file)
@@ -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;
index 558eb08c19ef9da28b233e4418353a32b0172260..281b3a7187cec2ff355aae17a4cec2b59d2102ca 100644 (file)
@@ -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);
index f7973ccd84a287017db736ca4dcb9baf150b1b2b..c6e4e0d1f2147e6221c10e607859354d2c1a32be 100644 (file)
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
 
-#define USB_VENDOR_ID_GLORIOUS  0x258a
-#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
-#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
-
 #define I2C_VENDOR_ID_GOODIX           0x27c6
 #define I2C_DEVICE_ID_GOODIX_01F0      0x01f0
 
 #define USB_VENDOR_ID_LABTEC           0x1020
 #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
 
+#define USB_VENDOR_ID_LAVIEW           0x22D4
+#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503
+
 #define USB_VENDOR_ID_LCPOWER          0x1241
 #define USB_DEVICE_ID_LCPOWER_LC1000   0xf767
 
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2         0xc534
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1      0xc539
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1    0xc53f
-#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2    0xc547
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
 #define USB_DEVICE_ID_SPACETRAVELLER   0xc623
 #define USB_DEVICE_ID_SPACENAVIGATOR   0xc626
 #define USB_VENDOR_ID_SIGMATEL         0x066F
 #define USB_DEVICE_ID_SIGMATEL_STMP3780        0x3780
 
+#define USB_VENDOR_ID_SINOWEALTH  0x258a
+#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033
+#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036
+
 #define USB_VENDOR_ID_SIS_TOUCH                0x0457
 #define USB_DEVICE_ID_SIS9200_TOUCH    0x9200
 #define USB_DEVICE_ID_SIS817_TOUCH     0x0817
index 8afe3be683ba251617e5b5f2b9477738ce2f13d7..e6a8b6d8eab707da539cbc209f205d0ef02bba67 100644 (file)
@@ -1695,12 +1695,11 @@ static int logi_dj_raw_event(struct hid_device *hdev,
                }
                /*
                 * Mouse-only receivers send unnumbered mouse data. The 27 MHz
-                * receiver uses 6 byte packets, the nano receiver 8 bytes,
-                * the lightspeed receiver (Pro X Superlight) 13 bytes.
+                * receiver uses 6 byte packets, the nano receiver 8 bytes.
                 */
                if (djrcv_dev->unnumbered_application == HID_GD_MOUSE &&
-                   size <= 13){
-                       u8 mouse_report[14];
+                   size <= 8) {
+                       u8 mouse_report[9];
 
                        /* Prepend report id */
                        mouse_report[0] = REPORT_TYPE_MOUSE;
@@ -1984,10 +1983,6 @@ static const struct hid_device_id logi_dj_receivers[] = {
          HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
                USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
         .driver_data = recvr_type_gaming_hidpp},
-       { /* Logitech lightspeed receiver (0xc547) */
-         HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
-               USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
-        .driver_data = recvr_type_gaming_hidpp},
 
        { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
          HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
index 72883e0ce75758c948683b0cee7377ecfd5c19fa..aef0785c91cc2d19385b54c8689be4e875aa85c9 100644 (file)
@@ -1142,6 +1142,8 @@ static int mcp2221_probe(struct hid_device *hdev,
        if (ret)
                return ret;
 
+       hid_device_io_start(hdev);
+
        /* Set I2C bus clock diviser */
        if (i2c_clk_freq > 400)
                i2c_clk_freq = 400;
@@ -1157,12 +1159,12 @@ static int mcp2221_probe(struct hid_device *hdev,
        snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
                        "MCP2221 usb-i2c bridge");
 
+       i2c_set_adapdata(&mcp->adapter, mcp);
        ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter);
        if (ret) {
                hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret);
                return ret;
        }
-       i2c_set_adapdata(&mcp->adapter, mcp);
 
 #if IS_REACHABLE(CONFIG_GPIOLIB)
        /* Setup GPIO chip */
index e098cc7b3944375387bb8003ca6ab4807bfb3eb9..fd5b0637dad683e7b20c929974c958e79936880c 100644 (file)
@@ -2046,6 +2046,11 @@ static const struct hid_device_id mt_devices[] = {
                MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
                        USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
 
+       /* HONOR GLO-GXXX panel */
+       { .driver_data = MT_CLS_VTL,
+               HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+                       0x347d, 0x7853) },
+
        /* Ilitek dual touch panel */
        {  .driver_data = MT_CLS_NSMU,
                MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
index 5a48fcaa32f007cddda7f18bf1b79261553f675a..ea472923fab07841ba6ee136da95a4a060690c4d 100644 (file)
@@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS },
        { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD },
        { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
index 5a8387a4a7126303adcee9553cce3cfb7599e1b2..bf43f3ff666400fb8a5d0fcef9e1c20773dcde1e 100644 (file)
@@ -679,6 +679,7 @@ struct hid_device {                                                 /* device report descriptor */
        struct list_head debug_list;
        spinlock_t  debug_list_lock;
        wait_queue_head_t debug_wait;
+       struct kref                     ref;
 
        unsigned int id;                                                /* system unique id */
 
@@ -687,6 +688,8 @@ struct hid_device {                                                 /* device report descriptor */
 #endif /* CONFIG_BPF */
 };
 
+void hiddev_free(struct kref *ref);
+
 #define to_hid_device(pdev) \
        container_of(pdev, struct hid_device, dev)