hid-for-linus-2025082901

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmixtiMACgkQpmLzj2vt
 YEkMhBAAmpdDXi5YyUkU+8qwZpIfPHUR9k+pv6vIfcALNZVy1siaspwZvWdX4GHw
 ghxQoH/L84rN6bhiHBG/8FrX2TUNizstQro6/wDc4G2EcXde9h0/SZOqqUaszR51
 1O09ns4Po9UI4ekHepx9vrCk+mSDDTRTptw0ALSo/RvqtnzeoCR+7EfGRjAVOY+z
 K2yEk5c6rmYocARHqmNrOWQEiUA94seLjCjKKkJdkzRRb3o9NU+uj1uixIlDsIIh
 SpxG/c1fqPxETOX+JNMm9L/7PQkTrMigdwtlTxvimj1CFXZtOMB6gDo4V1Qc5kuH
 yGcgfr+3mO1u3hfQ43nowz9Fuxrnru3qanP9TvY1/uBE+HPuXr4Nz09KEmJAC61l
 NBz3CqapCAo2tMA+BWHlmjdf3WufwlMQerVSipx0tn5ULfx7qJk3Nn1y4toef3qb
 9tDoN/tbFMA/IEfUwe/eHRFy4/Z5YgS7H/mTPp9UEtM0r/MwONwBSuGehY1dV2M9
 O9gNoUog8h3NbGbGLy9Fkb+c2Q9wXh4ISkvxJmfRBUJQemGxzEjTOhqk0jUalzo4
 AwhpE/BqPNb8dm52PhjZjXLefah8J03sZXN6TIpAS5vuDI9P97Ypa7Z6UGDjB4ao
 289r5xLsMRaUV6swTZNcgYoYj5oSEmpHNxody53W9v0Hn5ZjL7s=
 =WR2w
 -----END PGP SIGNATURE-----

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

Pull HID fixes from Jiri Kosina:

 - fixes for memory corruption in intel-thc-hid, hid-multitouch,
   hid-mcp2221 and hid-asus (Aaron Ma, Qasim Ijaz, Arnaud Lecomte)

 - power management/resume fix for intel-ish-hid (Zhang Lixu)

 - driver reinitialization fix for intel-thc-hid (Even Xu)

 - ensure that battery level status is reported as soon as possible,
   which is required at least for some Android use-cases (José Expósito)

 - quite a few new device ID additions and device-specific quirks

* tag 'hid-for-linus-2025082901' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: quirks: add support for Legion Go dual dinput modes
  HID: elecom: add support for ELECOM M-DT2DRBK
  HID: logitech: Add ids for G PRO 2 LIGHTSPEED
  HID: input: report battery status changes immediately
  HID: input: rename hidinput_set_battery_charge_status()
  HID: intel-thc-hid: Intel-quicki2c: Enhance driver re-install flow
  HID: hid-ntrig: fix unable to handle page fault in ntrig_report_version()
  HID: asus: fix UAF via HID_CLAIMED_INPUT validation
  hid: fix I2C read buffer overflow in raw_event() for mcp2221
  HID: wacom: Add a new Art Pen 2
  HID: multitouch: fix slab out-of-bounds access in mt_report_fixup()
  HID: Kconfig: Fix spelling mistake "enthropy" -> "entropy"
  HID: intel-ish-hid: Increase ISHTP resume ack timeout to 300ms
  HID: intel-thc-hid: intel-thc: Fix incorrect pointer arithmetic in I2C regs save
  HID: intel-thc-hid: intel-quicki2c: Fix ACPI dsd ICRS/ISUB length
pull/1334/head
Linus Torvalds 2025-08-29 07:44:14 -07:00
commit 02d6eeedbc
20 changed files with 79 additions and 42 deletions

View File

@ -1243,7 +1243,7 @@ config HID_U2FZERO
U2F Zero supports custom commands for blinking the LED U2F Zero supports custom commands for blinking the LED
and getting data from the internal hardware RNG. and getting data from the internal hardware RNG.
The internal hardware can be used to feed the enthropy pool. The internal hardware can be used to feed the entropy pool.
U2F Zero only supports blinking its LED, so this driver doesn't U2F Zero only supports blinking its LED, so this driver doesn't
allow setting the brightness to anything but 1, which will allow setting the brightness to anything but 1, which will

View File

@ -1213,7 +1213,13 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret; return ret;
} }
if (!drvdata->input) { /*
* Check that input registration succeeded. Checking that
* HID_CLAIMED_INPUT is set prevents a UAF when all input devices
* were freed during registration due to no usages being mapped,
* leaving drvdata->input pointing to freed memory.
*/
if (!drvdata->input || !(hdev->claimed & HID_CLAIMED_INPUT)) {
hid_err(hdev, "Asus input not registered\n"); hid_err(hdev, "Asus input not registered\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_stop_hw; goto err_stop_hw;

View File

@ -101,6 +101,7 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
*/ */
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8); mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
break; break;
case USB_DEVICE_ID_ELECOM_M_DT2DRBK:
case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C: case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C:
/* /*
* Report descriptor format: * Report descriptor format:
@ -123,6 +124,7 @@ static const struct hid_device_id elecom_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },

View File

@ -451,6 +451,7 @@
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd #define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
#define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe #define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
#define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff #define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
#define USB_DEVICE_ID_ELECOM_M_DT2DRBK 0x018d
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_010C 0x010c #define USB_DEVICE_ID_ELECOM_M_HT1URBK_010C 0x010c
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_019B 0x019b #define USB_DEVICE_ID_ELECOM_M_HT1URBK_019B 0x019b
#define USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D 0x010d #define USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D 0x010d
@ -834,6 +835,8 @@
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
#define USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT 0x6184
#define USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT 0x61ed
#define USB_VENDOR_ID_LETSKETCH 0x6161 #define USB_VENDOR_ID_LETSKETCH 0x6161
#define USB_DEVICE_ID_WP9620N 0x4d15 #define USB_DEVICE_ID_WP9620N 0x4d15
@ -907,6 +910,7 @@
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534 #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 0xc539
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc543
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548 #define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623 #define USB_DEVICE_ID_SPACETRAVELLER 0xc623

View File

@ -7,7 +7,7 @@
#include <kunit/test.h> #include <kunit/test.h>
static void hid_test_input_set_battery_charge_status(struct kunit *test) static void hid_test_input_update_battery_charge_status(struct kunit *test)
{ {
struct hid_device *dev; struct hid_device *dev;
bool handled; bool handled;
@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0); handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
KUNIT_EXPECT_FALSE(test, handled); KUNIT_EXPECT_FALSE(test, handled);
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN); KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0); handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
KUNIT_EXPECT_TRUE(test, handled); KUNIT_EXPECT_TRUE(test, handled);
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING); KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1); handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
KUNIT_EXPECT_TRUE(test, handled); KUNIT_EXPECT_TRUE(test, handled);
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING); KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
} }
@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
} }
static struct kunit_case hid_input_tests[] = { static struct kunit_case hid_input_tests[] = {
KUNIT_CASE(hid_test_input_set_battery_charge_status), KUNIT_CASE(hid_test_input_update_battery_charge_status),
KUNIT_CASE(hid_test_input_get_battery_property), KUNIT_CASE(hid_test_input_get_battery_property),
{ } { }
}; };

View File

@ -595,13 +595,33 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
dev->battery = NULL; dev->battery = NULL;
} }
static void hidinput_update_battery(struct hid_device *dev, int value) static bool hidinput_update_battery_charge_status(struct hid_device *dev,
unsigned int usage, int value)
{
switch (usage) {
case HID_BAT_CHARGING:
dev->battery_charge_status = value ?
POWER_SUPPLY_STATUS_CHARGING :
POWER_SUPPLY_STATUS_DISCHARGING;
return true;
}
return false;
}
static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
int value)
{ {
int capacity; int capacity;
if (!dev->battery) if (!dev->battery)
return; return;
if (hidinput_update_battery_charge_status(dev, usage, value)) {
power_supply_changed(dev->battery);
return;
}
if (value == 0 || value < dev->battery_min || value > dev->battery_max) if (value == 0 || value < dev->battery_min || value > dev->battery_max)
return; return;
@ -617,20 +637,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
power_supply_changed(dev->battery); power_supply_changed(dev->battery);
} }
} }
static bool hidinput_set_battery_charge_status(struct hid_device *dev,
unsigned int usage, int value)
{
switch (usage) {
case HID_BAT_CHARGING:
dev->battery_charge_status = value ?
POWER_SUPPLY_STATUS_CHARGING :
POWER_SUPPLY_STATUS_DISCHARGING;
return true;
}
return false;
}
#else /* !CONFIG_HID_BATTERY_STRENGTH */ #else /* !CONFIG_HID_BATTERY_STRENGTH */
static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
struct hid_field *field, bool is_percentage) struct hid_field *field, bool is_percentage)
@ -642,15 +648,10 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
{ {
} }
static void hidinput_update_battery(struct hid_device *dev, int value) static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
int value)
{ {
} }
static bool hidinput_set_battery_charge_status(struct hid_device *dev,
unsigned int usage, int value)
{
return false;
}
#endif /* CONFIG_HID_BATTERY_STRENGTH */ #endif /* CONFIG_HID_BATTERY_STRENGTH */
static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field, static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field,
@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
return; return;
if (usage->type == EV_PWR) { if (usage->type == EV_PWR) {
bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value); hidinput_update_battery(hid, usage->hid, value);
if (!handled)
hidinput_update_battery(hid, value);
return; return;
} }

View File

@ -1983,6 +1983,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1), USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
.driver_data = recvr_type_gaming_hidpp}, .driver_data = recvr_type_gaming_hidpp},
{ /* Logitech lightspeed receiver (0xc543) */
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) */ { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),

View File

@ -4596,6 +4596,8 @@ static const struct hid_device_id hidpp_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) }, HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
{ /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */ { /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) }, HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
{ /* Logitech G PRO 2 LIGHTSPEED Wireless Mouse over USB */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xc09a) },
{ /* G935 Gaming Headset */ { /* G935 Gaming Headset */
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87), HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),

View File

@ -906,6 +906,10 @@ static int mcp2221_raw_event(struct hid_device *hdev,
} }
if (data[2] == MCP2221_I2C_READ_COMPL || if (data[2] == MCP2221_I2C_READ_COMPL ||
data[2] == MCP2221_I2C_READ_PARTIAL) { data[2] == MCP2221_I2C_READ_PARTIAL) {
if (!mcp->rxbuf || mcp->rxbuf_idx < 0 || data[3] > 60) {
mcp->status = -EINVAL;
break;
}
buf = mcp->rxbuf; buf = mcp->rxbuf;
memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]); memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
mcp->rxbuf_idx = mcp->rxbuf_idx + data[3]; mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];

View File

@ -1503,6 +1503,14 @@ static const __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if (hdev->vendor == I2C_VENDOR_ID_GOODIX && if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 || (hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) { hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
if (*size < 608) {
dev_info(
&hdev->dev,
"GT7868Q fixup: report descriptor is only %u bytes, skipping\n",
*size);
return rdesc;
}
if (rdesc[607] == 0x15) { if (rdesc[607] == 0x15) {
rdesc[607] = 0x25; rdesc[607] = 0x25;
dev_info( dev_info(

View File

@ -144,6 +144,9 @@ static void ntrig_report_version(struct hid_device *hdev)
struct usb_device *usb_dev = hid_to_usb_dev(hdev); struct usb_device *usb_dev = hid_to_usb_dev(hdev);
unsigned char *data = kmalloc(8, GFP_KERNEL); unsigned char *data = kmalloc(8, GFP_KERNEL);
if (!hid_is_usb(hdev))
return;
if (!data) if (!data)
goto err_free; goto err_free;

View File

@ -124,6 +124,8 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
@ -411,6 +413,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },

View File

@ -264,9 +264,6 @@ static void ish_shutdown(struct pci_dev *pdev)
static struct device __maybe_unused *ish_resume_device; static struct device __maybe_unused *ish_resume_device;
/* 50ms to get resume response */
#define WAIT_FOR_RESUME_ACK_MS 50
/** /**
* ish_resume_handler() - Work function to complete resume * ish_resume_handler() - Work function to complete resume
* @work: work struct * @work: work struct

View File

@ -759,6 +759,9 @@ static void hid_ishtp_cl_resume_handler(struct work_struct *work)
if (ishtp_wait_resume(ishtp_get_ishtp_device(hid_ishtp_cl))) { if (ishtp_wait_resume(ishtp_get_ishtp_device(hid_ishtp_cl))) {
client_data->suspended = false; client_data->suspended = false;
wake_up_interruptible(&client_data->ishtp_resume_wait); wake_up_interruptible(&client_data->ishtp_resume_wait);
} else {
hid_ishtp_trace(client_data, "hid client: wait for resume timed out");
dev_err(cl_data_to_dev(client_data), "wait for resume timed out");
} }
} }

View File

@ -852,9 +852,6 @@ EXPORT_SYMBOL(ishtp_device);
*/ */
bool ishtp_wait_resume(struct ishtp_device *dev) bool ishtp_wait_resume(struct ishtp_device *dev)
{ {
/* 50ms to get resume response */
#define WAIT_FOR_RESUME_ACK_MS 50
/* Waiting to get resume response */ /* Waiting to get resume response */
if (dev->resume_flag) if (dev->resume_flag)
wait_event_interruptible_timeout(dev->resume_wait, wait_event_interruptible_timeout(dev->resume_wait,

View File

@ -47,6 +47,9 @@
#define MAX_DMA_DELAY 20 #define MAX_DMA_DELAY 20
/* 300ms to get resume response */
#define WAIT_FOR_RESUME_ACK_MS 300
/* ISHTP device states */ /* ISHTP device states */
enum ishtp_dev_state { enum ishtp_dev_state {
ISHTP_DEV_INITIALIZING = 0, ISHTP_DEV_INITIALIZING = 0,

View File

@ -419,6 +419,7 @@ static struct quicki2c_device *quicki2c_dev_init(struct pci_dev *pdev, void __io
*/ */
static void quicki2c_dev_deinit(struct quicki2c_device *qcdev) static void quicki2c_dev_deinit(struct quicki2c_device *qcdev)
{ {
thc_interrupt_quiesce(qcdev->thc_hw, true);
thc_interrupt_enable(qcdev->thc_hw, false); thc_interrupt_enable(qcdev->thc_hw, false);
thc_ltr_unconfig(qcdev->thc_hw); thc_ltr_unconfig(qcdev->thc_hw);
thc_wot_unconfig(qcdev->thc_hw); thc_wot_unconfig(qcdev->thc_hw);

View File

@ -77,6 +77,7 @@ struct quicki2c_subip_acpi_parameter {
u16 device_address; u16 device_address;
u64 connection_speed; u64 connection_speed;
u8 addressing_mode; u8 addressing_mode;
u8 reserved;
} __packed; } __packed;
/** /**
@ -126,6 +127,7 @@ struct quicki2c_subip_acpi_config {
u64 HMTD; u64 HMTD;
u64 HMRD; u64 HMRD;
u64 HMSL; u64 HMSL;
u8 reserved;
}; };
/** /**

View File

@ -1540,7 +1540,7 @@ int thc_i2c_subip_regs_save(struct thc_device *dev)
for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) { for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i], ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
&read_size, (u32 *)&dev->i2c_subip_regs + i); &read_size, &dev->i2c_subip_regs[i]);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
@ -1563,7 +1563,7 @@ int thc_i2c_subip_regs_restore(struct thc_device *dev)
for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) { for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i], ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
write_size, (u32 *)&dev->i2c_subip_regs + i); write_size, &dev->i2c_subip_regs[i]);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }

View File

@ -684,6 +684,7 @@ static bool wacom_is_art_pen(int tool_id)
case 0x885: /* Intuos3 Marker Pen */ case 0x885: /* Intuos3 Marker Pen */
case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */ case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */
case 0x204: /* Art Pen 2 */
is_art_pen = true; is_art_pen = true;
break; break;
} }