From patchwork Fri Dec 18 14:42:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 7885761 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 800EA9F1AF for ; Fri, 18 Dec 2015 14:42:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 932C720480 for ; Fri, 18 Dec 2015 14:42:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8DD8020497 for ; Fri, 18 Dec 2015 14:42:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753816AbbLROmR (ORCPT ); Fri, 18 Dec 2015 09:42:17 -0500 Received: from mga09.intel.com ([134.134.136.24]:21777 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750936AbbLROmO (ORCPT ); Fri, 18 Dec 2015 09:42:14 -0500 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP; 18 Dec 2015 06:42:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,446,1444719600"; d="scan'208";a="864027721" Received: from lahna.fi.intel.com (HELO lahna) ([10.237.72.56]) by fmsmga001.fm.intel.com with SMTP; 18 Dec 2015 06:42:10 -0800 Received: by lahna (sSMTP sendmail emulation); Fri, 18 Dec 2015 16:42:09 +0200 Date: Fri, 18 Dec 2015 16:42:09 +0200 From: Mika Westerberg To: Nish Aravamudan Cc: Jiri Kosina , Benjamin Tissoires , Andrew Duggan , Gabriele Mazzotta , Seth Forshee , Dan Carpenter , linux-input@vger.kernel.org, "linux-kernel@vger.kernel.org" Subject: Re: [RESEND] Lenovo Yoga 900 touchpad issues Message-ID: <20151218144209.GK1762@lahna.fi.intel.com> References: <20151216092858.GP1762@lahna.fi.intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Wed, Dec 16, 2015 at 02:58:11PM -0800, Nish Aravamudan wrote: > With the patch applied to my patched 4.4-rc5, things seem to be > working now. I do get one "failed to reset device" message in the > logs, but then I'm guessing the second one succeeds and I don't see > the "failed to resume" message. I finally got the yoga 900 machine. This is what happens when I have "i2c_hid.debug=1" in the kernel command line (I stripped out non-related messages and added few more debug prints): [ 72.410282] i2c_hid i2c-SYNA2B29:00: enabled IRQ [ 72.410285] i2c_hid i2c-SYNA2B29:00: i2c_hid_hwreset [ 72.410288] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_power [ 72.410291] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 00 08 [ 72.412879] i2c_hid i2c-SYNA2B29:00: resetting... [ 72.412883] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 00 01 Now we sent out reset command and wait for the interrupt to happen. [ 72.413248] i2c_hid i2c-SYNA2B29:00: input: 06 00 01 00 00 00 We get interrupt here but the received message did not have first two bytes zeroed as expected by the driver and the i2c-hid spec so we think it is an input report! [ 72.413266] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_or_send_report [ 72.413270] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 3f 03 0f 23 00 04 00 0f 01 [ 72.413416] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: waiting... Here we start actually waiting for the interrupt which already happened. [ 72.413751] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_or_send_report [ 72.413755] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=25 00 17 00 09 01 42 00 2e 00 19 19 00 10 cc 06 74 04 0f 19 00 00 00 00 00 [ 77.413135] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: finished. [ 77.413137] i2c_hid i2c-SYNA2B29:00: failed to reset device. And after 5 seconds we report error. [ 77.413138] i2c_hid i2c-SYNA2B29:00: i2c_hid_set_power [ 77.413139] i2c_hid i2c-SYNA2B29:00: __i2c_hid_command: cmd=22 00 01 08 [ 77.415030] i2c_hid i2c-SYNA2B29:00: reset returned: -61 [ 77.415035] dpm_run_callback(): i2c_hid_resume+0x0/0xe0 returns -61 [ 77.415037] PM: Device i2c-SYNA2B29:00 failed to resume: error -61 On another occasion the faulty input report was received immediatelly after we call i2c_hid_set_power(). With below hack patch suspend/resume works fine but it is far from being suitable for merging. Still, it would be nice if you could try it out and see if it helps in your case. --- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 10bd8e6..1c6969f 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -354,14 +354,19 @@ static int i2c_hid_hwreset(struct i2c_client *client) struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; + disable_irq(ihid->irq); + i2c_hid_dbg(ihid, "%s\n", __func__); ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); - if (ret) + if (ret) { + enable_irq(ihid->irq); return ret; + } i2c_hid_dbg(ihid, "resetting...\n"); + enable_irq(ihid->irq); ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0); if (ret) { dev_err(&client->dev, "failed to reset device.\n"); @@ -390,16 +395,14 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) return; } - ret_size = ihid->inbuf[0] | ihid->inbuf[1] << 8; - - if (!ret_size) { - /* host or device initiated RESET completed */ - if (test_and_clear_bit(I2C_HID_RESET_PENDING, &ihid->flags)) - wake_up(&ihid->wait); + /* host or device initiated RESET completed */ + if (test_and_clear_bit(I2C_HID_RESET_PENDING, &ihid->flags)) { + wake_up(&ihid->wait); return; } - if (ret_size > size) { + ret_size = ihid->inbuf[0] | ihid->inbuf[1] << 8; + if (ret_size > size || !ret_size) { dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", __func__, size, ret_size); return;