From patchwork Wed Sep 21 06:51:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Glauber X-Patchwork-Id: 672600 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3sf9Jz4DmLz9t0t for ; Wed, 21 Sep 2016 16:51:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751635AbcIUGvp (ORCPT ); Wed, 21 Sep 2016 02:51:45 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:34305 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751636AbcIUGvl (ORCPT ); Wed, 21 Sep 2016 02:51:41 -0400 Received: by mail-wm0-f66.google.com with SMTP id l132so6842981wmf.1; Tue, 20 Sep 2016 23:51:31 -0700 (PDT) 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:in-reply-to:references; bh=J9QIO6nNyiHFnBOI/opHVZSfpavgsrvJSrGx26uGxwo=; b=HTrAh/BR9QI5f/DA5yWXYcz2421n5ARl/W4P3MS5Cl8JFssvb9qqwX+/dWaik1ipo7 vcTJKfv5reKiblFwtVNNUx8tghubdIqChjOtSUNbxXMe3qGPdNcZNXFXH3qynFEO+W2D LMGVPlgTub/9FI5vXrnFmOjqseXUKre1+WMC7cTkNce1FqwDltCjyJXOrcig7l/zq45V MbG+4Zcc1TunZda1+1f+q4OwSIVpNJs353Sh9iuLZK7BvE6YA/bVEG6184JTbVE11iGA 7bTp/q+OGf6Y4ZGahSWGK7g0vzssTfW4VM0J/Izts/KinPdmz0E31IdGMyHDbHsUqwRh pc9A== X-Gm-Message-State: AE9vXwNbvN5nPXKAynkVrFpcprt5jxIc/xPlyg0YwhNJj0yP+2pxM6m+iKz3LYwO/RhEzg== X-Received: by 10.194.173.168 with SMTP id bl8mr31305295wjc.136.1474440690549; Tue, 20 Sep 2016 23:51:30 -0700 (PDT) Received: from wintermute.fritz.box (HSI-KBW-109-193-045-182.hsi7.kabel-badenwuerttemberg.de. [109.193.45.182]) by smtp.gmail.com with ESMTPSA id r194sm31012027wmf.22.2016.09.20.23.51.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 20 Sep 2016 23:51:30 -0700 (PDT) From: Jan Glauber To: Wolfram Sang Cc: linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org, Dmitry Bazhenov , Jan Glauber Subject: [PATCH 2/5] i2c: octeon, thunderx: Avoid sending STOP during recovery Date: Wed, 21 Sep 2016 08:51:03 +0200 Message-Id: <9791f6fb5fba70ddf9bd6b92e113e97bc0483317.1474439371.git.jglauber@cavium.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org From: Dmitry Bazhenov Due to a bug in the ThunderX I2C hardware sending STOP during a recovery attempt could lock up the hardware. To work around this problem do not send STOP at the beginning of the recovery but use the override registers to bring the TWSI including the high-level controller out of the bad state. Signed-off-by: Dmitry Bazhenov Signed-off-by: Jan Glauber [Changed commit message] --- drivers/i2c/busses/i2c-octeon-core.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c index f322242..7d4df83 100644 --- a/drivers/i2c/busses/i2c-octeon-core.c +++ b/drivers/i2c/busses/i2c-octeon-core.c @@ -783,13 +783,14 @@ static void octeon_i2c_prepare_recovery(struct i2c_adapter *adap) { struct octeon_i2c *i2c = i2c_get_adapdata(adap); + octeon_i2c_hlc_disable(i2c); + /* - * The stop resets the state machine, does not _transmit_ STOP unless - * engine was active. + * Bring control register to a good state regardless + * of HLC state. */ - octeon_i2c_stop(i2c); + octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB); - octeon_i2c_hlc_disable(i2c); octeon_i2c_write_int(i2c, 0); } @@ -797,6 +798,15 @@ static void octeon_i2c_unprepare_recovery(struct i2c_adapter *adap) { struct octeon_i2c *i2c = i2c_get_adapdata(adap); + /* + * Generate STOP to finish the unfinished transaction. + * Can't generate STOP via the TWSI CTL register + * since it could bring the TWSI controller into an inoperable state. + */ + octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR | TWSI_INT_SCL_OVR); + udelay(5); + octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR); + udelay(5); octeon_i2c_write_int(i2c, 0); }