Merge tag 'input-for-v6.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Oct 2023 06:19:16 +0000 (23:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Oct 2023 06:19:16 +0000 (23:19 -0700)
Pull input fixes from Dmitry Torokhov:

 - a reworked way for handling reset delay on SMBus-connected Synaptics
   touchpads (the original one, while being correct, uncovered an old
   bug in fallback to PS/2 code that was fixed separately; the new one
   however avoids having delay in serio port "fast" resume, and instead
   has the wait in the RMI4 code)

 - a fix for potential crashes when devices with Elan controllers (and
   Synaptics) fall back to PS/2 code. Can't be hit without the original
   patch above, but still good to have it fixed

 - a couple new device IDs in xpad Xbox driver

 - another quirk for Goodix driver to deal with stuff vendors put in
   ACPI tables

 - a fix for use-after-free on disconnect for powermate driver

 - a quirk to not initialize PS/2 mouse port on Fujitsu Lifebook E5411
   laptop as it makes keyboard not usable and the device uses
   hid-over-i2c touchpad anyways

* tag 'input-for-v6.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: powermate - fix use-after-free in powermate_config_complete
  Input: xpad - add PXN V900 support
  Input: synaptics-rmi4 - handle reset delay when using SMBus trsnsport
  Input: psmouse - fix fast_reconnect function for PS/2 mode
  Revert "Input: psmouse - add delay when deactivating for SMBus mode"
  Input: goodix - ensure int GPIO is in input for gpio_count == 1 && gpio_int_idx == 0 case
  Input: i8042 - add Fujitsu Lifebook E5411 to i8042 quirk table
  Input: xpad - add HyperX Clutch Gladiate Support

drivers/input/joystick/xpad.c
drivers/input/misc/powermate.c
drivers/input/mouse/elantech.c
drivers/input/mouse/psmouse-smbus.c
drivers/input/mouse/synaptics.c
drivers/input/rmi4/rmi_smbus.c
drivers/input/serio/i8042-acpipnpio.h
drivers/input/touchscreen/goodix.c

index ede3805..f5c2156 100644 (file)
@@ -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 },
@@ -272,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 },
@@ -459,6 +461,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 */
@@ -477,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 */
index c1c733a..db2ba89 100644 (file)
@@ -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);
index 2118b20..4e38229 100644 (file)
@@ -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;
index 7b13de9..2a2459b 100644 (file)
@@ -5,7 +5,6 @@
 
 #define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
 
-#include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/libps2.h>
@@ -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;
index ada299e..22d16d8 100644 (file)
@@ -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;
@@ -1752,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,
index 7059a27..b0b099b 100644 (file)
@@ -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);
 
index 1724d6c..9c39553 100644 (file)
@@ -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 = {
index da9954d..af32fbe 100644 (file)
@@ -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);