Merge branch 'next' into for-linus
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 15 Jan 2022 20:09:44 +0000 (12:09 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 15 Jan 2022 20:09:44 +0000 (12:09 -0800)
Prepare input updates for 5.17 merge window.

13 files changed:
Documentation/admin-guide/kernel-parameters.txt
drivers/input/joystick/spaceball.c
drivers/input/misc/iqs626a.c
drivers/input/mouse/appletouch.c
drivers/input/mouse/elantech.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/elants_i2c.c
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/goodix.h
drivers/input/touchscreen/goodix_fwupload.c
drivers/input/touchscreen/zinitix.c

index 43dc35fe5bc038ee93bd32f0c7fe641038427bd1..0c4361b4f8444a4d779cbbc9ef62549c0c084919 100644 (file)
                        architectures force reset to be always executed
        i8042.unlock    [HW] Unlock (ignore) the keylock
        i8042.kbdreset  [HW] Reset device connected to KBD port
+       i8042.probe_defer
+                       [HW] Allow deferred probing upon i8042 probe errors
 
        i810=           [HW,DRM]
 
index 429411c6c0a8ef18876196a39eed0e09bc265fc8..a85a4f33aea8ca11eb294a117ed79f335a5c145c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/serio.h>
+#include <asm/unaligned.h>
 
 #define DRIVER_DESC    "SpaceTec SpaceBall 2003/3003/4000 FLX driver"
 
@@ -75,9 +76,15 @@ static void spaceball_process_packet(struct spaceball* spaceball)
 
                case 'D':                                       /* Ball data */
                        if (spaceball->idx != 15) return;
-                       for (i = 0; i < 6; i++)
+                       /*
+                        * Skip first three bytes; read six axes worth of data.
+                        * Axis values are signed 16-bit big-endian.
+                        */
+                       data += 3;
+                       for (i = 0; i < ARRAY_SIZE(spaceball_axes); i++) {
                                input_report_abs(dev, spaceball_axes[i],
-                                       (__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
+                                       (__s16)get_unaligned_be16(&data[i * 2]));
+                       }
                        break;
 
                case 'K':                                       /* Button data */
index d57e996732cf4d9f8ddc2b7960bc808c64a9a67b..23b5dd9552dcc0539058a17ed2a19367cbb8add4 100644 (file)
@@ -456,9 +456,10 @@ struct iqs626_private {
        unsigned int suspend_mode;
 };
 
-static int iqs626_parse_events(struct iqs626_private *iqs626,
-                              const struct fwnode_handle *ch_node,
-                              enum iqs626_ch_id ch_id)
+static noinline_for_stack int
+iqs626_parse_events(struct iqs626_private *iqs626,
+                   const struct fwnode_handle *ch_node,
+                   enum iqs626_ch_id ch_id)
 {
        struct iqs626_sys_reg *sys_reg = &iqs626->sys_reg;
        struct i2c_client *client = iqs626->client;
@@ -604,9 +605,10 @@ static int iqs626_parse_events(struct iqs626_private *iqs626,
        return 0;
 }
 
-static int iqs626_parse_ati_target(struct iqs626_private *iqs626,
-                                  const struct fwnode_handle *ch_node,
-                                  enum iqs626_ch_id ch_id)
+static noinline_for_stack int
+iqs626_parse_ati_target(struct iqs626_private *iqs626,
+                       const struct fwnode_handle *ch_node,
+                       enum iqs626_ch_id ch_id)
 {
        struct iqs626_sys_reg *sys_reg = &iqs626->sys_reg;
        struct i2c_client *client = iqs626->client;
@@ -885,9 +887,10 @@ static int iqs626_parse_trackpad(struct iqs626_private *iqs626,
        return 0;
 }
 
-static int iqs626_parse_channel(struct iqs626_private *iqs626,
-                               const struct fwnode_handle *ch_node,
-                               enum iqs626_ch_id ch_id)
+static noinline_for_stack int
+iqs626_parse_channel(struct iqs626_private *iqs626,
+                    const struct fwnode_handle *ch_node,
+                    enum iqs626_ch_id ch_id)
 {
        struct iqs626_sys_reg *sys_reg = &iqs626->sys_reg;
        struct i2c_client *client = iqs626->client;
index bfa26651c0be7c8a5c2173e868a111ece3cb80ba..627048bc6a12e0ed3c2e62a36ca52159ca331efc 100644 (file)
@@ -916,6 +916,8 @@ static int atp_probe(struct usb_interface *iface,
        set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
        set_bit(BTN_LEFT, input_dev->keybit);
 
+       INIT_WORK(&dev->work, atp_reinit);
+
        error = input_register_device(dev->input);
        if (error)
                goto err_free_buffer;
@@ -923,8 +925,6 @@ static int atp_probe(struct usb_interface *iface,
        /* save our data pointer in this interface device */
        usb_set_intfdata(iface, dev);
 
-       INIT_WORK(&dev->work, atp_reinit);
-
        return 0;
 
  err_free_buffer:
index 956d9cd34796485cfde3b73da2300cea199cfe3f..ece97f8c6a3e399365b3f7c6a7e5d3f923c06ca7 100644 (file)
@@ -1588,7 +1588,13 @@ static const struct dmi_system_id no_hw_res_dmi_table[] = {
  */
 static int elantech_change_report_id(struct psmouse *psmouse)
 {
-       unsigned char param[2] = { 0x10, 0x03 };
+       /*
+        * NOTE: the code is expecting to receive param[] as an array of 3
+        * items (see __ps2_command()), even if in this case only 2 are
+        * actually needed. Make sure the array size is 3 to avoid potential
+        * stack out-of-bound accesses.
+        */
+       unsigned char param[3] = { 0x10, 0x03 };
 
        if (elantech_write_reg_params(psmouse, 0x7, param) ||
            elantech_read_reg_params(psmouse, 0x7, param) ||
index aedd0554104435e994793d7ad28cd2e26292a913..148a7c5fd0e22be932e922c6ba641b6df361e7b2 100644 (file)
@@ -995,6 +995,24 @@ static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
        { }
 };
 
+static const struct dmi_system_id i8042_dmi_probe_defer_table[] __initconst = {
+       {
+               /* ASUS ZenBook UX425UA */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
+               },
+       },
+       {
+               /* ASUS ZenBook UM325UA */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
+               },
+       },
+       { }
+};
+
 #endif /* CONFIG_X86 */
 
 #ifdef CONFIG_PNP
@@ -1315,6 +1333,9 @@ static int __init i8042_platform_init(void)
        if (dmi_check_system(i8042_dmi_kbdreset_table))
                i8042_kbdreset = true;
 
+       if (dmi_check_system(i8042_dmi_probe_defer_table))
+               i8042_probe_defer = true;
+
        /*
         * A20 was already enabled during early kernel init. But some buggy
         * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
index 0b9f1d0a8f8b0a703d1acf46058f27cdc460a441..3fc0a89cc785cb6b76bcaf49be8b573fb1682c8d 100644 (file)
@@ -45,6 +45,10 @@ static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
 MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
 
+static bool i8042_probe_defer;
+module_param_named(probe_defer, i8042_probe_defer, bool, 0);
+MODULE_PARM_DESC(probe_defer, "Allow deferred probing.");
+
 enum i8042_controller_reset_mode {
        I8042_RESET_NEVER,
        I8042_RESET_ALWAYS,
@@ -711,7 +715,7 @@ static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version)
  * LCS/Telegraphics.
  */
 
-static int __init i8042_check_mux(void)
+static int i8042_check_mux(void)
 {
        unsigned char mux_version;
 
@@ -740,10 +744,10 @@ static int __init i8042_check_mux(void)
 /*
  * The following is used to test AUX IRQ delivery.
  */
-static struct completion i8042_aux_irq_delivered __initdata;
-static bool i8042_irq_being_tested __initdata;
+static struct completion i8042_aux_irq_delivered;
+static bool i8042_irq_being_tested;
 
-static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
+static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id)
 {
        unsigned long flags;
        unsigned char str, data;
@@ -770,7 +774,7 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
  * verifies success by readinng CTR. Used when testing for presence of AUX
  * port.
  */
-static int __init i8042_toggle_aux(bool on)
+static int i8042_toggle_aux(bool on)
 {
        unsigned char param;
        int i;
@@ -798,7 +802,7 @@ static int __init i8042_toggle_aux(bool on)
  * the presence of an AUX interface.
  */
 
-static int __init i8042_check_aux(void)
+static int i8042_check_aux(void)
 {
        int retval = -1;
        bool irq_registered = false;
@@ -1005,7 +1009,7 @@ static int i8042_controller_init(void)
 
                if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
                        pr_err("Can't read CTR while initializing i8042\n");
-                       return -EIO;
+                       return i8042_probe_defer ? -EPROBE_DEFER : -EIO;
                }
 
        } while (n < 2 || ctr[0] != ctr[1]);
@@ -1320,7 +1324,7 @@ static void i8042_shutdown(struct platform_device *dev)
        i8042_controller_reset(false);
 }
 
-static int __init i8042_create_kbd_port(void)
+static int i8042_create_kbd_port(void)
 {
        struct serio *serio;
        struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
@@ -1349,7 +1353,7 @@ static int __init i8042_create_kbd_port(void)
        return 0;
 }
 
-static int __init i8042_create_aux_port(int idx)
+static int i8042_create_aux_port(int idx)
 {
        struct serio *serio;
        int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
@@ -1386,13 +1390,13 @@ static int __init i8042_create_aux_port(int idx)
        return 0;
 }
 
-static void __init i8042_free_kbd_port(void)
+static void i8042_free_kbd_port(void)
 {
        kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
        i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
 }
 
-static void __init i8042_free_aux_ports(void)
+static void i8042_free_aux_ports(void)
 {
        int i;
 
@@ -1402,7 +1406,7 @@ static void __init i8042_free_aux_ports(void)
        }
 }
 
-static void __init i8042_register_ports(void)
+static void i8042_register_ports(void)
 {
        int i;
 
@@ -1443,7 +1447,7 @@ static void i8042_free_irqs(void)
        i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
 }
 
-static int __init i8042_setup_aux(void)
+static int i8042_setup_aux(void)
 {
        int (*aux_enable)(void);
        int error;
@@ -1485,7 +1489,7 @@ static int __init i8042_setup_aux(void)
        return error;
 }
 
-static int __init i8042_setup_kbd(void)
+static int i8042_setup_kbd(void)
 {
        int error;
 
@@ -1535,7 +1539,7 @@ static int i8042_kbd_bind_notifier(struct notifier_block *nb,
        return 0;
 }
 
-static int __init i8042_probe(struct platform_device *dev)
+static int i8042_probe(struct platform_device *dev)
 {
        int error;
 
@@ -1600,6 +1604,7 @@ static struct platform_driver i8042_driver = {
                .pm     = &i8042_pm_ops,
 #endif
        },
+       .probe          = i8042_probe,
        .remove         = i8042_remove,
        .shutdown       = i8042_shutdown,
 };
@@ -1610,7 +1615,6 @@ static struct notifier_block i8042_kbd_bind_notifier_block = {
 
 static int __init i8042_init(void)
 {
-       struct platform_device *pdev;
        int err;
 
        dbg_init();
@@ -1626,17 +1630,29 @@ static int __init i8042_init(void)
        /* Set this before creating the dev to allow i8042_command to work right away */
        i8042_present = true;
 
-       pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
-       if (IS_ERR(pdev)) {
-               err = PTR_ERR(pdev);
+       err = platform_driver_register(&i8042_driver);
+       if (err)
                goto err_platform_exit;
+
+       i8042_platform_device = platform_device_alloc("i8042", -1);
+       if (!i8042_platform_device) {
+               err = -ENOMEM;
+               goto err_unregister_driver;
        }
 
+       err = platform_device_add(i8042_platform_device);
+       if (err)
+               goto err_free_device;
+
        bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
        panic_blink = i8042_panic_blink;
 
        return 0;
 
+err_free_device:
+       platform_device_put(i8042_platform_device);
+err_unregister_driver:
+       platform_driver_unregister(&i8042_driver);
  err_platform_exit:
        i8042_platform_exit();
        return err;
index 05de92c0293bca82889c7a94912e748368b8b1b6..eb66cd2689b7c64487910cacc75a97f231e804ef 100644 (file)
@@ -1882,7 +1882,7 @@ static int mxt_read_info_block(struct mxt_data *data)
        if (error) {
                dev_err(&client->dev, "Error %d parsing object table\n", error);
                mxt_free_object_table(data);
-               goto err_free_mem;
+               return error;
        }
 
        data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START);
index 7e13a66a8a95c8f9729ba7791df4cb97737b5a49..879a4d984c9078fecad5b88f395218396663ec7f 100644 (file)
 #define ELAN_POWERON_DELAY_USEC        500
 #define ELAN_RESET_DELAY_MSEC  20
 
+/* FW boot code version */
+#define BC_VER_H_BYTE_FOR_EKTH3900x1_I2C        0x72
+#define BC_VER_H_BYTE_FOR_EKTH3900x2_I2C        0x82
+#define BC_VER_H_BYTE_FOR_EKTH3900x3_I2C        0x92
+#define BC_VER_H_BYTE_FOR_EKTH5312x1_I2C        0x6D
+#define BC_VER_H_BYTE_FOR_EKTH5312x2_I2C        0x6E
+#define BC_VER_H_BYTE_FOR_EKTH5312cx1_I2C       0x77
+#define BC_VER_H_BYTE_FOR_EKTH5312cx2_I2C       0x78
+#define BC_VER_H_BYTE_FOR_EKTH5312x1_I2C_USB    0x67
+#define BC_VER_H_BYTE_FOR_EKTH5312x2_I2C_USB    0x68
+#define BC_VER_H_BYTE_FOR_EKTH5312cx1_I2C_USB   0x74
+#define BC_VER_H_BYTE_FOR_EKTH5312cx2_I2C_USB   0x75
+
 enum elants_chip_id {
        EKTH3500,
        EKTF3624,
@@ -736,6 +749,37 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,
        return 0;
 }
 
+static bool elants_i2c_should_check_remark_id(struct elants_data *ts)
+{
+       struct i2c_client *client = ts->client;
+       const u8 bootcode_version = ts->iap_version;
+       bool check;
+
+       /* I2C eKTH3900 and eKTH5312 are NOT support Remark ID */
+       if ((bootcode_version == BC_VER_H_BYTE_FOR_EKTH3900x1_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH3900x2_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH3900x3_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312x1_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312x2_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312cx1_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312cx2_I2C) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312x1_I2C_USB) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312x2_I2C_USB) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312cx1_I2C_USB) ||
+           (bootcode_version == BC_VER_H_BYTE_FOR_EKTH5312cx2_I2C_USB)) {
+               dev_dbg(&client->dev,
+                       "eKTH3900/eKTH5312(0x%02x) are not support remark id\n",
+                       bootcode_version);
+               check = false;
+       } else if (bootcode_version >= 0x60) {
+               check = true;
+       } else {
+               check = false;
+       }
+
+       return check;
+}
+
 static int elants_i2c_do_update_firmware(struct i2c_client *client,
                                         const struct firmware *fw,
                                         bool force)
@@ -749,7 +793,7 @@ static int elants_i2c_do_update_firmware(struct i2c_client *client,
        u16 send_id;
        int page, n_fw_pages;
        int error;
-       bool check_remark_id = ts->iap_version >= 0x60;
+       bool check_remark_id = elants_i2c_should_check_remark_id(ts);
 
        /* Recovery mode detection! */
        if (force) {
index ba84985b41c29210e54868c0e4507f9fff93a885..a3bfc7a4167974a5290da864abdff811a4f71ca1 100644 (file)
@@ -102,6 +102,7 @@ static const struct goodix_chip_id goodix_chip_ids[] = {
        { .id = "911", .data = &gt911_chip_data },
        { .id = "9271", .data = &gt911_chip_data },
        { .id = "9110", .data = &gt911_chip_data },
+       { .id = "9111", .data = &gt911_chip_data },
        { .id = "927", .data = &gt911_chip_data },
        { .id = "928", .data = &gt911_chip_data },
 
@@ -769,10 +770,16 @@ int goodix_reset_no_int_sync(struct goodix_ts_data *ts)
 
        usleep_range(6000, 10000);              /* T4: > 5ms */
 
-       /* end select I2C slave addr */
-       error = gpiod_direction_input(ts->gpiod_rst);
-       if (error)
-               goto error;
+       /*
+        * Put the reset pin back in to input / high-impedance mode to save
+        * power. Only do this in the non ACPI case since some ACPI boards
+        * don't have a pull-up, so there the reset pin must stay active-high.
+        */
+       if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_GPIO) {
+               error = gpiod_direction_input(ts->gpiod_rst);
+               if (error)
+                       goto error;
+       }
 
        return 0;
 
@@ -906,6 +913,14 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
                return -EINVAL;
        }
 
+       /*
+        * Normally we put the reset pin in input / high-impedance mode to save
+        * power. But some x86/ACPI boards don't have a pull-up, so for the ACPI
+        * case, leave the pin as is. This results in the pin not being touched
+        * at all on x86/ACPI boards, except when needed for error-recover.
+        */
+       ts->gpiod_rst_flags = GPIOD_ASIS;
+
        return devm_acpi_dev_add_driver_gpios(dev, gpio_mapping);
 }
 #else
@@ -931,6 +946,12 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
                return -EINVAL;
        dev = &ts->client->dev;
 
+       /*
+        * By default we request the reset pin as input, leaving it in
+        * high-impedance when not resetting the controller to save power.
+        */
+       ts->gpiod_rst_flags = GPIOD_IN;
+
        ts->avdd28 = devm_regulator_get(dev, "AVDD28");
        if (IS_ERR(ts->avdd28)) {
                error = PTR_ERR(ts->avdd28);
@@ -968,7 +989,7 @@ retry_get_irq_gpio:
        ts->gpiod_int = gpiod;
 
        /* Get the reset line GPIO pin number */
-       gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, GPIOD_IN);
+       gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, ts->gpiod_rst_flags);
        if (IS_ERR(gpiod)) {
                error = PTR_ERR(gpiod);
                if (error != -EPROBE_DEFER)
index f79eaeaceedbf27b05916a18e8c69750af110971..fa8602e78a6480c066103214cb06e475b36de6eb 100644 (file)
@@ -88,6 +88,7 @@ struct goodix_ts_data {
        struct gpio_desc *gpiod_rst;
        int gpio_count;
        int gpio_int_idx;
+       enum gpiod_flags gpiod_rst_flags;
        char id[GOODIX_ID_MAX_LEN + 1];
        char cfg_name[64];
        u16 version;
index c1e7a241307822933cc2b65d046fdade5cc5ed06..191d4f38d991ec52493f66d4a0b4d474d1f8df38 100644 (file)
@@ -207,7 +207,7 @@ static int goodix_firmware_upload(struct goodix_ts_data *ts)
 
        error = goodix_reset_no_int_sync(ts);
        if (error)
-               return error;
+               goto release;
 
        error = goodix_enter_upload_mode(ts->client);
        if (error)
index cf7ee4c765a76c755c65a7c15f5fb1ab4060008a..7c82c4f5fa6b331f2bf532c63c19a860ac13616e 100644 (file)
@@ -499,6 +499,15 @@ static int zinitix_ts_probe(struct i2c_client *client)
                return error;
        }
 
+       error = devm_request_threaded_irq(&client->dev, client->irq,
+                                         NULL, zinitix_ts_irq_handler,
+                                         IRQF_ONESHOT | IRQF_NO_AUTOEN,
+                                         client->name, bt541);
+       if (error) {
+               dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
+               return error;
+       }
+
        error = zinitix_init_input_dev(bt541);
        if (error) {
                dev_err(&client->dev,
@@ -524,15 +533,6 @@ static int zinitix_ts_probe(struct i2c_client *client)
                return -EINVAL;
        }
 
-       error = devm_request_threaded_irq(&client->dev, client->irq,
-                                         NULL, zinitix_ts_irq_handler,
-                                         IRQF_ONESHOT | IRQF_NO_AUTOEN,
-                                         client->name, bt541);
-       if (error) {
-               dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
-               return error;
-       }
-
        return 0;
 }