From e28a0974d749e5105d77233c0a84d35c37da047e Mon Sep 17 00:00:00 2001 From: Max Nguyen Date: Sun, 17 Sep 2023 22:21:53 -0700 Subject: [PATCH 1/8] Input: xpad - add HyperX Clutch Gladiate Support Add HyperX controller support to xpad_device and xpad_table. Suggested-by: Chris Toledanes Reviewed-by: Carl Ng Signed-off-by: Max Nguyen Reviewed-by: Rahul Rameshbabu Link: https://lore.kernel.org/r/20230906231514.4291-1-hphyperxdev@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index ede380551e55..b22f9c6e7fa5 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -130,6 +130,7 @@ static const struct xpad_device { { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 }, + { 0x03f0, 0x0495, "HyperX Clutch Gladiate", 0, XTYPE_XBOXONE }, { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, @@ -459,6 +460,7 @@ static const struct usb_device_id xpad_table[] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* Xbox USB-IF not-approved class */ XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 controller */ XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ + XPAD_XBOXONE_VENDOR(0x03f0), /* HP HyperX Xbox One controllers */ XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster Xbox 360 controllers */ XPAD_XBOX360_VENDOR(0x045e), /* Microsoft Xbox 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft Xbox One controllers */ From 80f39e1c27ba9e5a1ea7e68e21c569c9d8e46062 Mon Sep 17 00:00:00 2001 From: Szilard Fabian Date: Wed, 4 Oct 2023 05:47:01 -0700 Subject: [PATCH 2/8] Input: i8042 - add Fujitsu Lifebook E5411 to i8042 quirk table In the initial boot stage the integrated keyboard of Fujitsu Lifebook E5411 refuses to work and it's not possible to type for example a dm-crypt passphrase without the help of an external keyboard. i8042.nomux kernel parameter resolves this issue but using that a PS/2 mouse is detected. This input device is unused even when the i2c-hid-acpi kernel module is blacklisted making the integrated ELAN touchpad (04F3:308A) not working at all. Since the integrated touchpad is managed by the i2c_designware input driver in the Linux kernel and you can't find a PS/2 mouse port on the computer I think it's safe to not use the PS/2 mouse port at all. Signed-off-by: Szilard Fabian Link: https://lore.kernel.org/r/20231004011749.101789-1-szfabian@bluemarch.art Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-acpipnpio.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h index 1724d6cb8649..9c39553d30fa 100644 --- a/drivers/input/serio/i8042-acpipnpio.h +++ b/drivers/input/serio/i8042-acpipnpio.h @@ -618,6 +618,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { }, .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, + { + /* Fujitsu Lifebook E5411 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU CLIENT COMPUTING LIMITED"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E5411"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX) + }, { /* Gigabyte M912 */ .matches = { From 423622a90abb243944d1517b9f57db53729e45c4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 4 Oct 2023 07:18:31 -0700 Subject: [PATCH 3/8] Input: goodix - ensure int GPIO is in input for gpio_count == 1 && gpio_int_idx == 0 case Add a special case for gpio_count == 1 && gpio_int_idx == 0 to goodix_add_acpi_gpio_mappings(). It seems that on newer x86/ACPI devices the reset and irq GPIOs are no longer listed as GPIO resources instead there is only 1 GpioInt resource and _PS0 does the whole reset sequence for us. This means that we must call acpi_device_fix_up_power() on these devices to ensure that the chip is reset before we try to use it. This part was already fixed in commit 3de93e6ed2df ("Input: goodix - call acpi_device_fix_up_power() in some cases") by adding a call to acpi_device_fix_up_power() to the generic "Unexpected ACPI resources" catch all. But it turns out that this case on some hw needs some more special handling. Specifically the firmware may bootup with the IRQ pin in output mode. The reset sequence from ACPI _PS0 (executed by acpi_device_fix_up_power()) should put the pin in input mode, but the GPIO subsystem has cached the direction at bootup, causing request_irq() to fail due to gpiochip_lock_as_irq() failure: [ 9.119864] Goodix-TS i2c-GDIX1002:00: Unexpected ACPI resources: gpio_count 1, gpio_int_idx 0 [ 9.317443] Goodix-TS i2c-GDIX1002:00: ID 911, version: 1060 [ 9.321902] input: Goodix Capacitive TouchScreen as /devices/pci0000:00/0000:00:17.0/i2c_designware.4/i2c-5/i2c-GDIX1002:00/input/input8 [ 9.327840] gpio gpiochip0: (INT3453:00): gpiochip_lock_as_irq: tried to flag a GPIO set as output for IRQ [ 9.327856] gpio gpiochip0: (INT3453:00): unable to lock HW IRQ 26 for IRQ [ 9.327861] genirq: Failed to request resources for GDIX1002:00 (irq 131) on irqchip intel-gpio [ 9.327912] Goodix-TS i2c-GDIX1002:00: request IRQ failed: -5 Fix this by adding a special case for gpio_count == 1 && gpio_int_idx == 0 which adds an ACPI GPIO lookup table for the int GPIO even though we cannot use it for reset purposes (as there is no reset GPIO). Adding the lookup will make the gpiod_int = gpiod_get(..., GPIOD_IN) call succeed, which will explicitly set the direction to input fixing the issue. Note this re-uses the acpi_goodix_int_first_gpios[] lookup table, since there is only 1 GPIO in the ACPI resources the reset entry in that lookup table will amount to a no-op. Reported-and-tested-by: Michael Smith <1973.mjsmith@gmail.com> Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20231003215144.69527-1-hdegoede@redhat.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index da9954d6df44..af32fbe57b63 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -900,6 +900,25 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts) dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n"); ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO; gpio_mapping = acpi_goodix_int_last_gpios; + } else if (ts->gpio_count == 1 && ts->gpio_int_idx == 0) { + /* + * On newer devices there is only 1 GpioInt resource and _PS0 + * does the whole reset sequence for us. + */ + acpi_device_fix_up_power(ACPI_COMPANION(dev)); + + /* + * Before the _PS0 call the int GPIO may have been in output + * mode and the call should have put the int GPIO in input mode, + * but the GPIO subsys cached state may still think it is + * in output mode, causing gpiochip_lock_as_irq() failure. + * + * Add a mapping for the int GPIO to make the + * gpiod_int = gpiod_get(..., GPIOD_IN) call succeed, + * which will explicitly set the direction to input. + */ + ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE; + gpio_mapping = acpi_goodix_int_first_gpios; } else { dev_warn(dev, "Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d\n", ts->gpio_count, ts->gpio_int_idx); From b35726396390eb445668cecdbcd41d0285dbefdf Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 12 Oct 2023 15:54:21 -0700 Subject: [PATCH 4/8] Revert "Input: psmouse - add delay when deactivating for SMBus mode" This reverts commit 92e24e0e57f72e06c2df87116557331fd2d4dda2. While the patch itself is correct, it uncovered an issue with fallback to PS/2 mode, where we were leaving psmouse->fast_reconnect handler set to psmouse_smbus_reconnect(), which caused crashes. While discussing various approaches to fix the issue it was noted that this patch ass undesired delay in the "fast" resume path of PS/2 device, and it would be better to actually use "reset_delay" option defined in struct rmi_device_platform_data and have RMI code handle it for SMBus transport as well. So this patch is being reverted to deal with crashes and a better solution will be merged shortly. Reported-by: Thorsten Leemhuis Closes: https://lore.kernel.org/all/ca0109fa-c64b-43c1-a651-75b294d750a1@leemhuis.info/ Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-smbus.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c index 7b13de979908..2a2459b1b4f2 100644 --- a/drivers/input/mouse/psmouse-smbus.c +++ b/drivers/input/mouse/psmouse-smbus.c @@ -5,7 +5,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include @@ -119,18 +118,13 @@ static psmouse_ret_t psmouse_smbus_process_byte(struct psmouse *psmouse) return PSMOUSE_FULL_PACKET; } -static void psmouse_activate_smbus_mode(struct psmouse_smbus_dev *smbdev) -{ - if (smbdev->need_deactivate) { - psmouse_deactivate(smbdev->psmouse); - /* Give the device time to switch into SMBus mode */ - msleep(30); - } -} - static int psmouse_smbus_reconnect(struct psmouse *psmouse) { - psmouse_activate_smbus_mode(psmouse->private); + struct psmouse_smbus_dev *smbdev = psmouse->private; + + if (smbdev->need_deactivate) + psmouse_deactivate(psmouse); + return 0; } @@ -263,7 +257,8 @@ int psmouse_smbus_init(struct psmouse *psmouse, } } - psmouse_activate_smbus_mode(smbdev); + if (need_deactivate) + psmouse_deactivate(psmouse); psmouse->private = smbdev; psmouse->protocol_handler = psmouse_smbus_process_byte; From e2cb5cc822b6c9ee72c56ce1d81671b22c05406a Mon Sep 17 00:00:00 2001 From: Jeffery Miller Date: Fri, 13 Oct 2023 15:23:49 -0700 Subject: [PATCH 5/8] Input: psmouse - fix fast_reconnect function for PS/2 mode When the SMBus connection is attempted psmouse_smbus_init() sets the fast_reconnect pointer to psmouse_smbus_reconnecti(). If SMBus initialization fails, elantech_setup_ps2() and synaptics_init_ps2() will fallback to PS/2 mode, replacing the psmouse private data. This can cause issues on resume, since psmouse_smbus_reconnect() expects to find an instance of struct psmouse_smbus_dev in psmouse->private. The issue was uncovered when in 92e24e0e57f7 ("Input: psmouse - add delay when deactivating for SMBus mode") psmouse_smbus_reconnect() started attempting to use more of the data structure. The commit was since reverted, not because it was at fault, but because there was found a better way of doing what it was attempting to do. Fix the problem by resetting the fast_reconnect pointer in psmouse structure in elantech_setup_ps2() and synaptics_init_ps2() when the PS/2 mode is used. Reported-by: Thorsten Leemhuis Tested-by: Thorsten Leemhuis Signed-off-by: Jeffery Miller Fixes: bf232e460a35 ("Input: psmouse-smbus - allow to control psmouse_deactivate") Link: https://lore.kernel.org/r/20231005002249.554877-1-jefferymiller@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elantech.c | 1 + drivers/input/mouse/synaptics.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 2118b2075f43..4e38229404b4 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -2114,6 +2114,7 @@ static int elantech_setup_ps2(struct psmouse *psmouse, psmouse->protocol_handler = elantech_process_byte; psmouse->disconnect = elantech_disconnect; psmouse->reconnect = elantech_reconnect; + psmouse->fast_reconnect = NULL; psmouse->pktsize = info->hw_version > 1 ? 6 : 4; return 0; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ada299ec5bba..cefc74b3b34b 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1623,6 +1623,7 @@ static int synaptics_init_ps2(struct psmouse *psmouse, psmouse->set_rate = synaptics_set_rate; psmouse->disconnect = synaptics_disconnect; psmouse->reconnect = synaptics_reconnect; + psmouse->fast_reconnect = NULL; psmouse->cleanup = synaptics_reset; /* Synaptics can usually stay in sync without extra help */ psmouse->resync_time = 0; From 5030b2fe6aab37fe42d14f31842ea38be7c55c57 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 13 Oct 2023 17:29:57 -0700 Subject: [PATCH 6/8] Input: synaptics-rmi4 - handle reset delay when using SMBus trsnsport Touch controllers need some time after receiving reset command for the firmware to finish re-initializing and be ready to respond to commands from the host. The driver already had handling for the post-reset delay for I2C and SPI transports, this change adds the handling to SMBus-connected devices. SMBus devices are peculiar because they implement legacy PS/2 compatibility mode, so reset is actually issued by psmouse driver on the associated serio port, after which the control is passed to the RMI4 driver with SMBus companion device. Note that originally the delay was added to psmouse driver in 92e24e0e57f7 ("Input: psmouse - add delay when deactivating for SMBus mode"), but that resulted in an unwanted delay in "fast" reconnect handler for the serio port, so it was decided to revert the patch and have the delay being handled in the RMI4 driver, similar to the other transports. Tested-by: Jeffery Miller Link: https://lore.kernel.org/r/ZR1yUFJ8a9Zt606N@penguin Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 1 + drivers/input/rmi4/rmi_smbus.c | 50 ++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index cefc74b3b34b..22d16d80efb9 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1753,6 +1753,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse, psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10); const struct rmi_device_platform_data pdata = { + .reset_delay_ms = 30, .sensor_pdata = { .sensor_type = rmi_sensor_touchpad, .axis_align.flip_y = true, diff --git a/drivers/input/rmi4/rmi_smbus.c b/drivers/input/rmi4/rmi_smbus.c index 7059a2762aeb..b0b099b5528a 100644 --- a/drivers/input/rmi4/rmi_smbus.c +++ b/drivers/input/rmi4/rmi_smbus.c @@ -235,12 +235,29 @@ static void rmi_smb_clear_state(struct rmi_smb_xport *rmi_smb) static int rmi_smb_enable_smbus_mode(struct rmi_smb_xport *rmi_smb) { - int retval; + struct i2c_client *client = rmi_smb->client; + int smbus_version; + + /* + * psmouse driver resets the controller, we only need to wait + * to give the firmware chance to fully reinitialize. + */ + if (rmi_smb->xport.pdata.reset_delay_ms) + msleep(rmi_smb->xport.pdata.reset_delay_ms); /* we need to get the smbus version to activate the touchpad */ - retval = rmi_smb_get_version(rmi_smb); - if (retval < 0) - return retval; + smbus_version = rmi_smb_get_version(rmi_smb); + if (smbus_version < 0) + return smbus_version; + + rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", + smbus_version); + + if (smbus_version != 2 && smbus_version != 3) { + dev_err(&client->dev, "Unrecognized SMB version %d\n", + smbus_version); + return -ENODEV; + } return 0; } @@ -253,11 +270,10 @@ static int rmi_smb_reset(struct rmi_transport_dev *xport, u16 reset_addr) rmi_smb_clear_state(rmi_smb); /* - * we do not call the actual reset command, it has to be handled in - * PS/2 or there will be races between PS/2 and SMBus. - * PS/2 should ensure that a psmouse_reset is called before - * intializing the device and after it has been removed to be in a known - * state. + * We do not call the actual reset command, it has to be handled in + * PS/2 or there will be races between PS/2 and SMBus. PS/2 should + * ensure that a psmouse_reset is called before initializing the + * device and after it has been removed to be in a known state. */ return rmi_smb_enable_smbus_mode(rmi_smb); } @@ -272,7 +288,6 @@ static int rmi_smb_probe(struct i2c_client *client) { struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev); struct rmi_smb_xport *rmi_smb; - int smbus_version; int error; if (!pdata) { @@ -311,18 +326,9 @@ static int rmi_smb_probe(struct i2c_client *client) rmi_smb->xport.proto_name = "smb"; rmi_smb->xport.ops = &rmi_smb_ops; - smbus_version = rmi_smb_get_version(rmi_smb); - if (smbus_version < 0) - return smbus_version; - - rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", - smbus_version); - - if (smbus_version != 2 && smbus_version != 3) { - dev_err(&client->dev, "Unrecognized SMB version %d\n", - smbus_version); - return -ENODEV; - } + error = rmi_smb_enable_smbus_mode(rmi_smb); + if (error) + return error; i2c_set_clientdata(client, rmi_smb); From a65cd7ef5a864bdbbe037267c327786b7759d4c6 Mon Sep 17 00:00:00 2001 From: Matthias Berndt Date: Fri, 13 Oct 2023 15:04:36 -0700 Subject: [PATCH 7/8] Input: xpad - add PXN V900 support Add VID and PID to the xpad_device table to allow driver to use the PXN V900 steering wheel, which is XTYPE_XBOX360 compatible in xinput mode. Signed-off-by: Matthias Berndt Link: https://lore.kernel.org/r/4932699.31r3eYUQgx@fedora Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index b22f9c6e7fa5..f5c21565bb3c 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -273,6 +273,7 @@ static const struct xpad_device { { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 }, + { 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 }, { 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 }, { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 }, @@ -479,6 +480,7 @@ static const struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries controllers */ XPAD_XBOXONE_VENDOR(0x10f5), /* Turtle Beach Controllers */ XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */ + XPAD_XBOX360_VENDOR(0x11ff), /* PXN V900 */ XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */ XPAD_XBOX360_VENDOR(0x12ab), /* Xbox 360 dance pads */ XPAD_XBOX360_VENDOR(0x1430), /* RedOctane Xbox 360 controllers */ From 5c15c60e7be615f05a45cd905093a54b11f461bc Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Fri, 13 Oct 2023 20:11:33 -0700 Subject: [PATCH 8/8] Input: powermate - fix use-after-free in powermate_config_complete syzbot has found a use-after-free bug [1] in the powermate driver. This happens when the device is disconnected, which leads to a memory free from the powermate_device struct. When an asynchronous control message completes after the kfree and its callback is invoked, the lock does not exist anymore and hence the bug. Use usb_kill_urb() on pm->config to cancel any in-progress requests upon device disconnection. [1] https://syzkaller.appspot.com/bug?extid=0434ac83f907a1dbdd1e Signed-off-by: Javier Carrasco Reported-by: syzbot+0434ac83f907a1dbdd1e@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20230916-topic-powermate_use_after_free-v3-1-64412b81a7a2@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/powermate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index c1c733a9cb89..db2ba89adaef 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c @@ -425,6 +425,7 @@ static void powermate_disconnect(struct usb_interface *intf) pm->requires_update = 0; usb_kill_urb(pm->irq); input_unregister_device(pm->input); + usb_kill_urb(pm->config); usb_free_urb(pm->irq); usb_free_urb(pm->config); powermate_free_buffers(interface_to_usbdev(intf), pm);