Commit 9207fe75 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull HID fixes from Jiri Kosina:

 - fix for 'MSC_SERIAL = 0' corner case handling in wacom driver (Jason
   Gerecke)

 - ACPI S3 suspend/resume fix for intel-ish-hid (Even Xu)

 - race condition fix preventing Wacom driver from losing events shortly
   after initialization (Jason Gerecke)

 - fix preventing certain Logitech HID++ devices from spamming kernel
   log (Oleksandr Natalenko)

* tag 'hid-for-linus-2024021501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: wacom: generic: Avoid reporting a serial of '0' to userspace
  HID: Intel-ish-hid: Ishtp: Fix sensor reads after ACPI S3 suspend
  HID: multitouch: Add required quirk for Synaptics 0xcddc device
  HID: wacom: Do not register input devices until after hid_hw_start
  HID: logitech-hidpp: Do not flood kernel log
parents 8d3dea21 ab41a31d
......@@ -203,6 +203,8 @@ struct hidpp_device {
struct hidpp_scroll_counter vertical_wheel_counter;
u8 wireless_feature_index;
bool connected_once;
};
/* HID++ 1.0 error codes */
......@@ -988,8 +990,13 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
hidpp->protocol_minor = response.rap.params[1];
print_version:
hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
hidpp->protocol_major, hidpp->protocol_minor);
if (!hidpp->connected_once) {
hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
hidpp->protocol_major, hidpp->protocol_minor);
hidpp->connected_once = true;
} else
hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
hidpp->protocol_major, hidpp->protocol_minor);
return 0;
}
......@@ -4184,7 +4191,7 @@ static void hidpp_connect_event(struct work_struct *work)
/* Get device version to check if it is connected */
ret = hidpp_root_get_protocol_version(hidpp);
if (ret) {
hid_info(hidpp->hid_dev, "Disconnected\n");
hid_dbg(hidpp->hid_dev, "Disconnected\n");
if (hidpp->battery.ps) {
hidpp->battery.online = false;
hidpp->battery.status = POWER_SUPPLY_STATUS_UNKNOWN;
......
......@@ -2151,6 +2151,10 @@ static const struct hid_device_id mt_devices[] = {
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_SYNAPTICS, 0xcd7e) },
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_SYNAPTICS, 0xcddc) },
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_SYNAPTICS, 0xce08) },
......
......@@ -722,6 +722,8 @@ void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
spin_lock_irqsave(&ishtp_dev->cl_list_lock, flags);
list_for_each_entry(cl, &ishtp_dev->cl_list, link) {
cl->state = ISHTP_CL_DISCONNECTED;
if (warm_reset && cl->device->reference_count)
continue;
/*
* Wake any pending process. The waiter would check dev->state
......
......@@ -49,7 +49,9 @@ static void ishtp_read_list_flush(struct ishtp_cl *cl)
list_for_each_entry_safe(rb, next, &cl->dev->read_list.list, list)
if (rb->cl && ishtp_cl_cmp_id(cl, rb->cl)) {
list_del(&rb->list);
ishtp_io_rb_free(rb);
spin_lock(&cl->free_list_spinlock);
list_add_tail(&rb->list, &cl->free_rb_list.list);
spin_unlock(&cl->free_list_spinlock);
}
spin_unlock_irqrestore(&cl->dev->read_list_spinlock, flags);
}
......
......@@ -2087,7 +2087,7 @@ static int wacom_allocate_inputs(struct wacom *wacom)
return 0;
}
static int wacom_register_inputs(struct wacom *wacom)
static int wacom_setup_inputs(struct wacom *wacom)
{
struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev;
struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
......@@ -2106,10 +2106,6 @@ static int wacom_register_inputs(struct wacom *wacom)
input_free_device(pen_input_dev);
wacom_wac->pen_input = NULL;
pen_input_dev = NULL;
} else {
error = input_register_device(pen_input_dev);
if (error)
goto fail;
}
error = wacom_setup_touch_input_capabilities(touch_input_dev, wacom_wac);
......@@ -2118,10 +2114,6 @@ static int wacom_register_inputs(struct wacom *wacom)
input_free_device(touch_input_dev);
wacom_wac->touch_input = NULL;
touch_input_dev = NULL;
} else {
error = input_register_device(touch_input_dev);
if (error)
goto fail;
}
error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
......@@ -2130,7 +2122,34 @@ static int wacom_register_inputs(struct wacom *wacom)
input_free_device(pad_input_dev);
wacom_wac->pad_input = NULL;
pad_input_dev = NULL;
} else {
}
return 0;
}
static int wacom_register_inputs(struct wacom *wacom)
{
struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev;
struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
int error = 0;
pen_input_dev = wacom_wac->pen_input;
touch_input_dev = wacom_wac->touch_input;
pad_input_dev = wacom_wac->pad_input;
if (pen_input_dev) {
error = input_register_device(pen_input_dev);
if (error)
goto fail;
}
if (touch_input_dev) {
error = input_register_device(touch_input_dev);
if (error)
goto fail;
}
if (pad_input_dev) {
error = input_register_device(pad_input_dev);
if (error)
goto fail;
......@@ -2383,6 +2402,20 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
if (error)
goto fail;
error = wacom_setup_inputs(wacom);
if (error)
goto fail;
if (features->type == HID_GENERIC)
connect_mask |= HID_CONNECT_DRIVER;
/* Regular HID work starts now */
error = hid_hw_start(hdev, connect_mask);
if (error) {
hid_err(hdev, "hw start failed\n");
goto fail;
}
error = wacom_register_inputs(wacom);
if (error)
goto fail;
......@@ -2397,16 +2430,6 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
goto fail;
}
if (features->type == HID_GENERIC)
connect_mask |= HID_CONNECT_DRIVER;
/* Regular HID work starts now */
error = hid_hw_start(hdev, connect_mask);
if (error) {
hid_err(hdev, "hw start failed\n");
goto fail;
}
if (!wireless) {
/* Note that if query fails it is not a hard failure */
wacom_query_tablet_data(wacom);
......
......@@ -2575,7 +2575,14 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
wacom_wac->hid_data.tipswitch);
input_report_key(input, wacom_wac->tool[0], sense);
if (wacom_wac->serial[0]) {
input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]);
/*
* xf86-input-wacom does not accept a serial number
* of '0'. Report the low 32 bits if possible, but
* if they are zero, report the upper ones instead.
*/
__u32 serial_lo = wacom_wac->serial[0] & 0xFFFFFFFFu;
__u32 serial_hi = wacom_wac->serial[0] >> 32;
input_event(input, EV_MSC, MSC_SERIAL, (int)(serial_lo ? serial_lo : serial_hi));
input_report_abs(input, ABS_MISC, sense ? id : 0);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment