From patchwork Mon Aug 1 11:14:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcos Paulo de Souza X-Patchwork-Id: 9254277 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BCE8760865 for ; Mon, 1 Aug 2016 11:16:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD3AA28460 for ; Mon, 1 Aug 2016 11:16:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A1DF528494; Mon, 1 Aug 2016 11:16:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 08ECC28460 for ; Mon, 1 Aug 2016 11:16:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753044AbcHALQj (ORCPT ); Mon, 1 Aug 2016 07:16:39 -0400 Received: from mail-qk0-f195.google.com ([209.85.220.195]:34118 "EHLO mail-qk0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752425AbcHALPh (ORCPT ); Mon, 1 Aug 2016 07:15:37 -0400 Received: by mail-qk0-f195.google.com with SMTP id s186so5565426qkb.1; Mon, 01 Aug 2016 04:15:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DqPlMqZA8PlWf0Uwl79z6eX7WC5Q55sfvusF0S/sSWM=; b=F/3YG/SJ0JBYn4zCeUx00rtp5W3JrRTz799yk+M0STGfXBueC59sYcI/EaUYy6qjBG D2zVrGW+VC6+OoSwuNa25P3rmb7N1DnRw9zB6bURBJOoC9l9UMYISaYAkLGhsa5O+gjV Hirzxrcvr2dTcy1Gg4rBc4x1fhDdj2R78/GtTEGnor6fIDlc5dbpQ2bjiwBJXx+CPhtx swVmWpL+Ahp9LgI7uSWtnBB239NU1dXj6aO96g8ZRZo7tUgCMHsJfe4DWpi+YlMf5InW yH92OCMX36rImcCbNDCYaRVNeoZuroFDg1aPFC4Zrjcl/QyS3u7uj0s63CqaF5RfLnoL 8pfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DqPlMqZA8PlWf0Uwl79z6eX7WC5Q55sfvusF0S/sSWM=; b=GkjWRqSsKn9zs5yiTAQ6lfE8yCCjQoqw+JENkOeqXlE4+FEPIHGLRU+wXuRCYOpsIY l7xx++8m7Tm8bPxT3vVN0ObuH0mFlvJqL5Tvezfyr7oOu0D/UOh5g1iAEedFePccR8NI gL4DySao2WABP7QoIokNNSlGas6J6IN6kqZq8Q202bDnyX5VS9ik11lprm+D4BqHdVnk YYHwEJeE7ppYEBrkAE19/UDASrKYFgagWwufD3PAnAdOKs29KeT+OPFJkYf/xmD2J9rd dUDZJ6O+fyn3Yn/HjYbFHaOXB1UmSrz2yA7yrKTYsjXwLe2sfoGyifrARYbZqlAKffA8 2/Mw== X-Gm-Message-State: AEkooutRl4jXj+tByhtO3AuQpfANPapQssc7cjM+UsIZBE86oprtQkVItnzM9VBZ+eAPww== X-Received: by 10.55.153.70 with SMTP id b67mr68950221qke.190.1470050124736; Mon, 01 Aug 2016 04:15:24 -0700 (PDT) Received: from localhost.localdomain ([187.112.244.56]) by smtp.gmail.com with ESMTPSA id 55sm17317494qtp.32.2016.08.01.04.15.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Aug 2016 04:15:24 -0700 (PDT) From: Marcos Paulo de Souza To: dmitry.torokhov@gmail.com Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, Marcos Paulo de Souza Subject: [PATCH v2 1/2] input/serio/i8042.c: Skipt selftest on some ASUS laptops Date: Mon, 1 Aug 2016 08:14:02 -0300 Message-Id: <1470050043-4403-2-git-send-email-marcos.souza.org@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1470050043-4403-1-git-send-email-marcos.souza.org@gmail.com> References: <1470050043-4403-1-git-send-email-marcos.souza.org@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On suspend/resume cycle, selftest is executed on to reset i8042 controller. But when this is done in these devices, posterior calls to detect/init functions to elantech driver fails. Skipping selftest fixes this problem. An easier step to reproduce this problem is adding i8042.reset=1 parameter. On problematic laptops, it'll make the system to start with the touchpad already stucked, since i8042 code forcibly calls the selftest function. This patch was inspired by John Hiesey's change[1]. [1]: https://marc.info/?l=linux-input&m=144312209020616&w=2 Fixes: "ETPS/2 Elantech Touchpad dies after resume from suspend" (https://bugzilla.kernel.org/show_bug.cgi?id=107971) Signed-off-by: Marcos Paulo de Souza --- drivers/input/serio/i8042-x86ia64io.h | 70 ++++++++++++++++++++++++++++++++++- drivers/input/serio/i8042.c | 38 ++++++++++++++++--- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 68f5f4a..0107976 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -510,6 +510,66 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { { } }; +/* + * On some hardware just running the self test causes problems. + */ +static const struct dmi_system_id __initconst i8042_dmi_noselftest_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "K401LB"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "K501LB"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "K501LD"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "K501LX"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X302LA"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X450LD"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X455LAB"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X455LDB"), + }, + }, + { } +}; static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { { /* MSI Wind U-100 */ @@ -1076,8 +1136,14 @@ static int __init i8042_platform_init(void) #endif #ifdef CONFIG_X86 - if (dmi_check_system(i8042_dmi_reset_table)) - i8042_reset = true; + /* Honor module parameter when value is not default */ + if (i8042_reset == I8042_RESET_ON_RESUME) { + if (dmi_check_system(i8042_dmi_reset_table)) + i8042_reset = I8042_RESET_ALWAYS; + + if (dmi_check_system(i8042_dmi_noselftest_table)) + i8042_reset = I8042_RESET_NEVER; + } if (dmi_check_system(i8042_dmi_noloop_table)) i8042_noloop = true; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 4541957..28ce5d2 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -48,9 +48,32 @@ static bool i8042_unlock; module_param_named(unlock, i8042_unlock, bool, 0); MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); -static bool i8042_reset; -module_param_named(reset, i8042_reset, bool, 0); -MODULE_PARM_DESC(reset, "Reset controller during init and cleanup."); +enum i8042_controller_reset_mode { + I8042_RESET_NEVER, + I8042_RESET_ALWAYS, + I8042_RESET_ON_RESUME +}; +static unsigned int i8042_reset = I8042_RESET_ON_RESUME; +static int i8042_set_reset(const char *val, const struct kernel_param *kp) +{ + unsigned int ret = I8042_RESET_ON_RESUME; + if (!val || !strncmp(val, "1", 1) || !strncasecmp(val, "y", 1)) + ret = I8042_RESET_ALWAYS; + else if (!strncmp(val, "0", 1) || !strncasecmp(val, "n", 1)) + ret = I8042_RESET_NEVER; + + *((unsigned int *)kp->arg) = ret; + + return 0; +} + +static const struct kernel_param_ops param_ops_reset_param = { + .flags = KERNEL_PARAM_OPS_FL_NOARG, + .set = i8042_set_reset, +}; +#define param_check_reset_param(name, p) __param_check(name, p, unsigned int) +module_param_named(reset, i8042_reset, reset_param, 0); +MODULE_PARM_DESC(reset, "Reset controller on resume, cleanup or both"); static bool i8042_direct; module_param_named(direct, i8042_direct, bool, 0); @@ -890,6 +913,9 @@ static int i8042_controller_selftest(void) unsigned char param; int i = 0; + if (i8042_reset == I8042_RESET_NEVER) + return 0; + /* * We try this 5 times; on some really fragile systems this does not * take the first time... @@ -1044,7 +1070,7 @@ static void i8042_controller_reset(bool force_reset) * Reset the controller if requested. */ - if (i8042_reset || force_reset) + if (force_reset) i8042_controller_selftest(); /* @@ -1118,7 +1144,7 @@ static int i8042_controller_resume(bool force_reset) if (error) return error; - if (i8042_reset || force_reset) { + if (force_reset) { error = i8042_controller_selftest(); if (error) return error; @@ -1495,7 +1521,7 @@ static int __init i8042_probe(struct platform_device *dev) i8042_platform_device = dev; - if (i8042_reset) { + if (i8042_reset == I8042_RESET_ALWAYS) { error = i8042_controller_selftest(); if (error) return error;