From patchwork Fri Sep 23 09:40:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Glauber X-Patchwork-Id: 674021 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 3sgSzr32qwz9t14 for ; Fri, 23 Sep 2016 19:41:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965615AbcIWJlY (ORCPT ); Fri, 23 Sep 2016 05:41:24 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:34557 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757333AbcIWJky (ORCPT ); Fri, 23 Sep 2016 05:40:54 -0400 Received: by mail-wm0-f67.google.com with SMTP id l132so1863164wmf.1; Fri, 23 Sep 2016 02:40:53 -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=gAnC+PbCoWNEhbjCv03DZQNjT43lR3kHoVKkq1Qzh0U=; b=SCCiydkqxRJjni3bNIKkoWcBaJAL0BgvF6INUcmOm2mTPS0T1zvQyJ0GSHBKaPIc/u FBQKfj/23l8Xj53vvufwQqEO8ToH5dDDq29ccOZY4DcF2rDdIudmrNbBRdXH89Ocau45 A8p89HKdMpMSp+OWIyOAcHiSA3+s1dLf4egcYmWqggc63oIRYQtPClHaP9P5ha/Mtw+7 uK47ceW4OYEY93htgpdQ2apaMHkR6d0qPuT3tUgr6rJS7RMhKs7VoBZCVQgowlV4VsCn ZsCuWVlcm16t0u3Dquk9BbtdB3SmTCJhHUuQgXiqlllYIZ4PfHYsRk+5ctcTe5acXe4V f4zQ== X-Gm-Message-State: AE9vXwNsaor5JjocjY/SR5Wo/xU2eOmvHwle0miidJDO0wVDMUPHq4OYlFjOCDdT8wd+9Q== X-Received: by 10.194.51.170 with SMTP id l10mr6882460wjo.203.1474623653033; Fri, 23 Sep 2016 02:40:53 -0700 (PDT) Received: from wintermute.fritz.box (HSI-KBW-46-223-65-126.hsi.kabel-badenwuerttemberg.de. [46.223.65.126]) by smtp.gmail.com with ESMTPSA id f10sm6306837wje.14.2016.09.23.02.40.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 23 Sep 2016 02:40:52 -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 v2 1/2] i2c: octeon: thunderx: Check bus state before starting a transaction Date: Fri, 23 Sep 2016 11:40:38 +0200 Message-Id: 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 Add an additional status check before starting a transaction. If the check fails wait for some time to tolerate multi-master mode. After the timeout expires trigger the recovery. Signed-off-by: Jan Glauber --- drivers/i2c/busses/i2c-octeon-core.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c index 5e63b17..f526511 100644 --- a/drivers/i2c/busses/i2c-octeon-core.c +++ b/drivers/i2c/busses/i2c-octeon-core.c @@ -630,6 +630,31 @@ static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msg return ret; } +static int octeon_i2c_check_bus(struct octeon_i2c *i2c) +{ + u64 end = get_jiffies_64() + i2c->adap.timeout; + int stat, lines; + + while (time_before64(get_jiffies_64(), end)) { + stat = octeon_i2c_stat_read(i2c); + + /* get I2C line state */ + lines = octeon_i2c_read_int(i2c) & (TWSI_INT_SCL | TWSI_INT_SDA); + + if (stat == STAT_IDLE && lines == (TWSI_INT_SCL | TWSI_INT_SDA)) + return 0; + + if (stat == STAT_LOST_ARB_38 || stat == STAT_LOST_ARB_68 || + stat == STAT_LOST_ARB_78 || stat == STAT_LOST_ARB_B0) + break; + + usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT); + } + + /* bus check failed, try to recover */ + return octeon_i2c_recovery(i2c); +} + /** * octeon_i2c_xfer - The driver's master_xfer function * @adap: Pointer to the i2c_adapter structure @@ -643,6 +668,10 @@ int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) struct octeon_i2c *i2c = i2c_get_adapdata(adap); int i, ret = 0; + ret = octeon_i2c_check_bus(i2c); + if (ret) + goto out; + if (num == 1) { if (msgs[0].len > 0 && msgs[0].len <= 8) { if (msgs[0].flags & I2C_M_RD)