Received: by 2002:ac0:98c7:0:0:0:0:0 with SMTP id g7-v6csp3485921imd; Mon, 29 Oct 2018 07:52:02 -0700 (PDT) X-Google-Smtp-Source: AJdET5esabRNdnbt/sHPgbRRGJQiqcbrqDEdFMISraDHABS+Dwk3CB1sJkShMj5Tna6+fqVMbQ24 X-Received: by 2002:a62:e30a:: with SMTP id g10-v6mr5405975pfh.151.1540824722678; Mon, 29 Oct 2018 07:52:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1540824722; cv=none; d=google.com; s=arc-20160816; b=ucMYEvD1mOoINXouFtwULGJ43zqM6ao9TnE2nvuBhib7J8rLd6M8y8W43nt/XpxRHF hRLldw5wiwvQNT574wqLy06oNy07dVILVM0VLiGtbV9gqIjbfgPb97MvWpKThUbuPOu4 oySNJa/g8u4dzlOcPjZ6ox5WPbLwk6keXZMq5AOZV4jdKkq/ihOmR8kIpZ3RAGF9VRrh GTBWFLM82jkG6QWKjX/V2V4ed17Y19auME8lpBeQCXx7VI3vPN/W9pV+8/aZezT7D/fY 4zkR4Dz0QivCjwrcBBjEqyuAMWRwQa05n7gmw9keOIyKQg/wJrzXihykMAbD1pslLlZq wAhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:spamdiagnosticmetadata :spamdiagnosticoutput:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=ECSIoVa8JW6O8tJu7FSlaxo4KybqvBjFMHglIfGO/yI=; b=bhzZSS06dfvXatY2ik02TY7BV9PnsXU0BZAHkgGDw7cfQmI/sD3tCirwsw1T7LK2Kf Qbt+LsLaQ0xt38IJPGkouagoONIKvDF3JU6Mb7zS857miwdCnv3GWW2oIjTshvKPusyq oTPSEqzNtuoQVuG7HokpllCP5+jEtKttINGJvDDzPM4LPSyBkAx2utTOueJEHFFfyY4z YXxu4sgFTXgk/cizhMBxVXFM3aYZTFw2abA+Z0XBvtmVrC9JW2FRILUQVWcTiXVtEZLi 1GN1UOisZVAPhA0Euj70lKfRBG4mOKFfwMmuGkV6N4dmA7PUlTmEPnhcM09VcybVSrv5 siBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cern.onmicrosoft.com header.s=selector1-cern-ch header.b=oIptsT5r; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i33-v6si21073689pld.433.2018.10.29.07.51.46; Mon, 29 Oct 2018 07:52:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@cern.onmicrosoft.com header.s=selector1-cern-ch header.b=oIptsT5r; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727412AbeJ2XkQ (ORCPT + 99 others); Mon, 29 Oct 2018 19:40:16 -0400 Received: from mail-eopbgr70075.outbound.protection.outlook.com ([40.107.7.75]:30965 "EHLO EUR04-HE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726451AbeJ2XkP (ORCPT ); Mon, 29 Oct 2018 19:40:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cern.onmicrosoft.com; s=selector1-cern-ch; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ECSIoVa8JW6O8tJu7FSlaxo4KybqvBjFMHglIfGO/yI=; b=oIptsT5rbydJnrkTaT2sasZ5p3U/qOi1Dc5ws6U6g+vxFdd8/raz2TFyVt3YxyyUfnSnb/+874G6K8vCN344qWOxAQ4sZN0TciiyrBPRlJ1W8oTM3dEPOMET1RZx1nFKmaY5cJpCE9066SMKJwZMfUM62X175LrxHK/AXRt52e4= Received: from VI1PR06CA0101.eurprd06.prod.outlook.com (2603:10a6:803:8c::30) by AM3PR06MB513.eurprd06.prod.outlook.com (2a01:111:e400:8825::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1273.26; Mon, 29 Oct 2018 14:51:12 +0000 Received: from HE1EUR02FT027.eop-EUR02.prod.protection.outlook.com (2a01:111:f400:7e05::203) by VI1PR06CA0101.outlook.office365.com (2603:10a6:803:8c::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1273.19 via Frontend Transport; Mon, 29 Oct 2018 14:51:12 +0000 Authentication-Results: spf=pass (sender IP is 188.184.36.50) smtp.mailfrom=cern.ch; korsgaard.com; dkim=none (message not signed) header.d=none;korsgaard.com; dmarc=bestguesspass action=none header.from=cern.ch; Received-SPF: Pass (protection.outlook.com: domain of cern.ch designates 188.184.36.50 as permitted sender) receiver=protection.outlook.com; client-ip=188.184.36.50; helo=cernmxgwlb4.cern.ch; Received: from cernmxgwlb4.cern.ch (188.184.36.50) by HE1EUR02FT027.mail.protection.outlook.com (10.152.10.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1294.14 via Frontend Transport; Mon, 29 Oct 2018 14:51:11 +0000 Received: from cernfe06.cern.ch (188.184.36.49) by cernmxgwlb4.cern.ch (188.184.36.50) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 29 Oct 2018 15:51:11 +0100 Received: from cwe-513-vol689.cern.ch (188.185.69.206) by smtp.cern.ch (188.184.36.52) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 29 Oct 2018 15:51:10 +0100 From: Federico Vaga To: Peter Korsgaard , CC: , Subject: [PATCH V2 1/5] i2c:ocores: stop transfer on timeout Date: Mon, 29 Oct 2018 15:50:47 +0100 Message-ID: <20181029145051.31984-2-federico.vaga@cern.ch> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20181029145051.31984-1-federico.vaga@cern.ch> References: <20181029145051.31984-1-federico.vaga@cern.ch> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [188.185.69.206] X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:188.184.36.50;IPV:NLI;CTRY:CH;EFV:NLI;SFV:NSPM;SFS:(10009020)(396003)(136003)(39860400002)(376002)(346002)(2980300002)(438002)(189003)(199004)(446003)(11346002)(74482002)(53416004)(956004)(4326008)(14444005)(2616005)(50466002)(476003)(126002)(186003)(305945005)(7636002)(7736002)(246002)(16526019)(106466001)(48376002)(426003)(44832011)(36756003)(486006)(66066001)(336012)(107886003)(7696005)(8676002)(6666004)(50226002)(356004)(8936002)(47776003)(26005)(6116002)(3846002)(478600001)(316002)(786003)(16586007)(51416003)(5660300001)(106002)(1076002)(54906003)(110136005)(86362001)(76176011)(2906002);DIR:OUT;SFP:1101;SCL:1;SRVR:AM3PR06MB513;H:cernmxgwlb4.cern.ch;FPR:;SPF:Pass;LANG:en;PTR:cernmx11.cern.ch;MX:1;A:1; X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ecbcdc42-9386-451b-0dcc-08d63dadf812 X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4608076)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020);SRVR:AM3PR06MB513; X-MS-TrafficTypeDiagnostic: AM3PR06MB513: X-Microsoft-Exchange-Diagnostics: 1;AM3PR06MB513;20:E18GwdYDZcatyNID5mrwtPsGeReFKW96c0lBEEiI2xuY6dFHbIi/rvGkHBfbhPyIABQzjjdRaw3y9QD8tY/yfL5/R3+Q6XRAJLOd8lQJVsRvlKYcUyemnXKfxqcWDyR+Ka47YyQ8bRZWXo7n1Kuc6EEmw3VtTlsudTmSiRmqqTEInsRD9vglkYiiAGzUhy7vJ9wffQyCV5yoUSFnkrUBAmDf++LFWuMD2ovhUX+7DrP/DKmRPfmwlXLDAH2gkctptiJ/NS9HcEWSRt+1avWZzSoHdyv9d3sRTRvdKLjm9IOXyxWYMPcOubDFhXN7M6Uxv9/f6KHeQlbgT9a9mtpf+97/VRXKdkes8rA6Ex4OGKj1IJifzhDxDpzrje+mKXeCOv8KerI7ASEHLrYT+QJbuxFmBDxu1pWeoZ0FkItUFDGl5TusN2Z4UxNRGSc+F/lKJzt7xC4y1gK8XzeneC8agnO+Is4xqchGJ8iLVlFqM9wcc0kNpGK6tiCFZRXzpznc;4:nogwMSsDYJAV7eqbkjUEhCOvqS6KqdbrXz0ExZV2MuI9Q45faPKVbTk/Yvr9EC4GRsgZ+IMMddLSJ5sTbEVel9DynPwk4HkHfZdP155brw2wYWDtUkN80nFQ7iAq9GhF6mdqCcU5K6EiPxBuWDxf2R/MtkRPZYfApBrofH6I1rbm5+yF+P2yrcfgzWYfCDkFPsqLzkHmQcr6BbEaTxgnzlPOd8rXuxEVQAfEHfQj4yjZe06o+AG/NmGAdVIAObqTvGHNWmkC4qa3FN5dsRZM/A== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231382)(944501410)(52105095)(93006095)(93004095)(10201501046)(3002001)(148016)(149066)(150057)(6041310)(201703131423095)(201702281529075)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201708071742011)(7699051)(76991095);SRVR:AM3PR06MB513;BCL:0;PCL:0;RULEID:;SRVR:AM3PR06MB513; X-Forefront-PRVS: 084080FC15 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM3PR06MB513;23:qCpsrjs7ObM4qdd9Ea4XGb0fJ8ixz5PDESavwVbzmw?= =?us-ascii?Q?tnpDttOTQCRXpRWGT6qsel2PZXRgmIEGoxCXurMGc4iOl2LxBhO0hE3f+w5C?= =?us-ascii?Q?YZxVcde8bCxZEHZZsEbOoMPhyqLeEcSuZ76qR966H4PFom7i43kBk2ebkrCE?= =?us-ascii?Q?mtMUo2MomG69mzILtD3CYjPV+Sn99PoELO39SERtTJVZE+/4enTyuGmDLfX8?= =?us-ascii?Q?OY7nh0HLIQzHjeGPr31S3Ax2Noocdsb6Zwmw/OH+APXFU/GMB4q4GpvHHpEQ?= =?us-ascii?Q?Amo9EdpY4yuin88fl4a8HCPJmuzO21qbcIni8SyFBXg7jlstXeW9VWDnOg9O?= =?us-ascii?Q?scZXnCuzyBN8LMLHsWEpI4yJLXg9ofWmHr9/coLuBM+gp2/yn9B7Xrwuwx5v?= =?us-ascii?Q?/qO9lMSEJWwbmCDd15Ao/i5PewoI/ZoRPEo3MYe9lGF7d34lqbNyGhXJWoX9?= =?us-ascii?Q?tvR40N8HtKW5ZQpghxST+lHc7am0POYoNh3cVs5ocrFFoAPRQjl0ebaV/z21?= =?us-ascii?Q?FV+AEzzPjwhjJ/RhZFTeG8N/eoV5d+nXiMWIiIMZ6Nj71qz/Wojx2x5Rk9Rk?= =?us-ascii?Q?PqnIERd9sHFJn+9DWkvvhGn75/uNHN5LCuBQjJFoUCXUYi+UoQgNnucXEKX9?= =?us-ascii?Q?jwW671iPaseq++pQBjf3EiPXrytxzQlAccT0Xasvu+JBPNEQ8Wd6dCVByeoE?= =?us-ascii?Q?27H8v/W9opMcywD1UJqGiYRk9L0KhT3DeaZOXLh/13ZyUctBZk3s20gGruyD?= =?us-ascii?Q?YszruVPGfRD2Oha87/9Y0ZD73whNCayYW1QrhO4f4ZVDxc0+JoWVTWlcDcVI?= =?us-ascii?Q?s90MOWZoCWpwD20f4qKAq407NjtvOJtcUN1zdkhApAO/hswz63GTHR2movMc?= =?us-ascii?Q?A9CUXsSNDiRbEV0RGm6msw9XNoaklAMqFgRFp1gkiT85amT8ZOK+LhkO0NpT?= =?us-ascii?Q?aoW5LIHSvyNXvdxdPcOtoR98c2f0oAsb5g+kj54erDewCW/eoyAbdUHCowuM?= =?us-ascii?Q?1UI0qMngrJ47ygGcE+6kaWZoTQQEaDR6v5MaMLL3UtM32HxYIKvqP1HD23Hn?= =?us-ascii?Q?uJf9ui8athqn6j8FEvbIBC+NauvlXf+59F3Gac6GWxHumEyR2FFrYl/podNC?= =?us-ascii?Q?1BoMxb+UijgcOYqqDNFAn7oZX5lPPo731PNG0xCZV3f5W6OsPPItPNPWuJlf?= =?us-ascii?Q?k90I0/GP3I5/3oR5tWm8U+Cz8fA5JwDyIkbUx4Kzx/0KEheToODrwliM0R89?= =?us-ascii?Q?ytyl5Ss+W18/+tfQE=3D?= X-Microsoft-Antispam-Message-Info: syUJMmVBUyP5QYGC49tqCTq0XPlTRNI3tC7ZwmQTANQAMqhV3gUaaW9rs2CAesx2aFjKBoQ6Fq2a3ERPd5GilDPWaewUyWQnJelKZ37dLlKD9XMNNbtnj4/iuF9sSAvko7KrY4YLeGx1xbozCdZyBJaN++ao2DkWyTV/nFJQG5wD/kKJe846/kOz1zGmRPfymEtIYVTYHdUG5Xf/kXIc2S+6EeGDFnX9lRHg7ue72K17qtYZhip4zP7rSYCze+AHe16E66dvuCVPYMlgctVbGXnQIjirrLKn/6AGcjZ4Z5hUur7qlheNKhmlAUl4XnQ32DkSPe6FX8KIC7EWiNodVaWqtbdIq3cmAUgtaefGzps= X-Microsoft-Exchange-Diagnostics: 1;AM3PR06MB513;6:bsl9IQmtyl3mOkbrQnnMS+RBS3AijOPPJQjIscNbe81I1T0d02xzXM7Vp5Kkk1GX4pyCgRQ0lLGZHolMvHz6f1cot9PhoxZSR2XtvBQTjN/03sJ5ocG+IvdCcaqZ0a45VAyBWmG/kJnnD/UU24v8peVmS2faf8JGj/YoY5hAoqSFURnU16yoZWun4ZXLg2Jm9hGIWfkD2GpTmOgotL8IOjtJEc+h0WCE59lL04MY7RSuepmJG0/HcDA8aOfwg2tEUFHS/9cjS/+tDPrHnp/EOn9V5wHovexcY3hk2cpr4ekwoZM23yf3ELc1j9VCx8AYAb29Zm+WSo0M1cHxg4ad2tVr9qX+ftOe6/e8dmcJJBoMQJY9haDAabwxeDFsnex/9mbGAlb9/piBVOj+ebSsePQXG/eEwYUF0b4RF+fzDi3g1EYoB8L3X62eieGYXebO6G85nGz+N4vd6rqESbkuPA==;5:+2Y50pBx/d4vIE9PbpL00c9dGFk4LzoS1yZXIt1fWdK/mjIhf22FXLwW5mlPJJvzU08Cfxc4sroYTBCrYBPUIk+MCuiYj7qqgKLGNtkRVtqGkZjSJl5czRvQ7qKwxoZiuu2/rXYqQVPPPrQZ8TjzSb/bqr15QiEHbGo90SgcV+I=;7:ChPWDEKKZxTYrkHln9pjzu5J6LhBkL+MMaOvb37L/fo2d/f4lWCtmJiuwk4E+ELb/ftqp8eVpnTiMkbJOp3/gFBQnaQ/B4xMNzKH1tqAGitgry2NWvcjos/W4VpifEtxj0zhwcettdqW+3fPvFqIzw== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cern.ch X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Oct 2018 14:51:11.3979 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ecbcdc42-9386-451b-0dcc-08d63dadf812 X-MS-Exchange-CrossTenant-Id: c80d3499-4a40-4a8c-986e-abce017d6b19 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=c80d3499-4a40-4a8c-986e-abce017d6b19;Ip=[188.184.36.50];Helo=[cernmxgwlb4.cern.ch] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR06MB513 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Detecting a timeout is ok, but we also need to assert a STOP command on the bus in order to prevent it from generating interrupts when there are no on going transfers. Example: very long transmission. 1. ocores_xfer: START a transfer 2. ocores_isr : handle byte by byte the transfer 3. ocores_xfer: goes in timeout [[bugfix here]] 4. ocores_xfer: return to I2C subsystem and to the I2C driver 5. I2C driver : it may clean up the i2c_msg memory 6. ocores_isr : receives another interrupt (pending bytes to be transferred) but the i2c_msg memory is invalid now So, since the transfer was too long, we have to detect the timeout and STOP the transfer. Another point is that we have a critical region here. When handling the timeout condition we may have a running IRQ handler. For this reason I introduce a spinlock. In order to make easier to understan locking I have: - added a new function to handle timeout - modified the current ocores_process() function in order to be protected by the new spinlock Like this it is obvious at first sight that this locking serializes the execution of ocores_process() and ocores_process_timeout() Signed-off-by: Federico Vaga --- drivers/i2c/busses/i2c-ocores.c | 54 ++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 87f9caa..aa85202 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -25,7 +25,12 @@ #include #include #include +#include +/** + * @process_lock: protect I2C transfer process. + * ocores_process() and ocores_process_timeout() can't run in parallel. + */ struct ocores_i2c { void __iomem *base; u32 reg_shift; @@ -36,6 +41,7 @@ struct ocores_i2c { int pos; int nmsgs; int state; /* see STATE_ */ + spinlock_t process_lock; struct clk *clk; int ip_clock_khz; int bus_clock_khz; @@ -141,19 +147,26 @@ static void ocores_process(struct ocores_i2c *i2c) { struct i2c_msg *msg = i2c->msg; u8 stat = oc_getreg(i2c, OCI2C_STATUS); + unsigned long flags; + + /* + * If we spin here is because we are in timeout, so we are going + * to be in STATE_ERROR. See ocores_process_timeout() + */ + spin_lock_irqsave(&i2c->process_lock, flags); if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { /* stop has been sent */ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); wake_up(&i2c->wait); - return; + goto out; } /* error? */ if (stat & OCI2C_STAT_ARBLOST) { i2c->state = STATE_ERROR; oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - return; + goto out; } if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { @@ -163,7 +176,7 @@ static void ocores_process(struct ocores_i2c *i2c) if (stat & OCI2C_STAT_NACK) { i2c->state = STATE_ERROR; oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - return; + goto out; } } else msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); @@ -184,14 +197,14 @@ static void ocores_process(struct ocores_i2c *i2c) oc_setreg(i2c, OCI2C_DATA, addr); oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - return; + goto out; } else i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; } else { i2c->state = STATE_DONE; oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); - return; + goto out; } } @@ -202,6 +215,9 @@ static void ocores_process(struct ocores_i2c *i2c) oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); } + +out: + spin_unlock_irqrestore(&i2c->process_lock, flags); } static irqreturn_t ocores_isr(int irq, void *dev_id) @@ -213,9 +229,24 @@ static irqreturn_t ocores_isr(int irq, void *dev_id) return IRQ_HANDLED; } +/** + * Process timeout event + * @i2c: ocores I2C device instance + */ +static void ocores_process_timeout(struct ocores_i2c *i2c) +{ + unsigned long flags; + + spin_lock_irqsave(&i2c->process_lock, flags); + i2c->state = STATE_ERROR; + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); + spin_unlock_irqrestore(&i2c->process_lock, flags); +} + static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { struct ocores_i2c *i2c = i2c_get_adapdata(adap); + int ret; i2c->msg = msgs; i2c->pos = 0; @@ -225,11 +256,14 @@ static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) oc_setreg(i2c, OCI2C_DATA, i2c_8bit_addr_from_msg(i2c->msg)); oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); - if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else + ret = wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ); + if (ret == 0) { + ocores_process_timeout(i2c); return -ETIMEDOUT; + } + + return (i2c->state == STATE_DONE) ? num : -EIO; } static int ocores_init(struct device *dev, struct ocores_i2c *i2c) @@ -422,6 +456,8 @@ static int ocores_i2c_probe(struct platform_device *pdev) if (!i2c) return -ENOMEM; + spin_lock_init(&i2c->process_lock); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(i2c->base)) -- 2.15.0