From patchwork Thu Nov 30 14:30:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrzej Hajda X-Patchwork-Id: 10085013 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 19F7C6035E for ; Thu, 30 Nov 2017 14:30:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 025352A02D for ; Thu, 30 Nov 2017 14:30:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EB4F02A040; Thu, 30 Nov 2017 14:30:30 +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_SIGNED, 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 885192A042 for ; Thu, 30 Nov 2017 14:30:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751288AbdK3Oa2 (ORCPT ); Thu, 30 Nov 2017 09:30:28 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:54700 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752524AbdK3OaW (ORCPT ); Thu, 30 Nov 2017 09:30:22 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20171130143020euoutp010e2592bf4b052bbabee2ddeef2a71f5b~743ulNqI50407604076euoutp01O; Thu, 30 Nov 2017 14:30:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20171130143020euoutp010e2592bf4b052bbabee2ddeef2a71f5b~743ulNqI50407604076euoutp01O DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1512052220; bh=X9HaNaJQmnhmLdyrJmIH5AnRAsaed3A7hMRunuXhHQw=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=It9W7CUuQ8TsVyGe+WJCoyHRLUxD9wCcFcywH7WQOBbAqJ9aJ8RrJsLSIWX/ldHtW JaeCvZq5SPdmrzrsl67kxVe09Ea7u0aAqIgBBFYCPlWRKSUc2+LOnl9cl5dpPX5BSY pwS1clj5/zBa4512dey+Ljcq3rYN1F3z/hOQJlhQ= Received: from eusmges3.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20171130143019eucas1p2c656130a19cafc502ef9bb518bf58cec~743tvdyfA2586225862eucas1p2e; Thu, 30 Nov 2017 14:30:19 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3.samsung.com (EUCPMTA) with SMTP id 7D.CE.12867.AF5102A5; Thu, 30 Nov 2017 14:30:18 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20171130143018eucas1p13bd2ce9263f9ac016ab3b779920b512e~743s9jiaI2061520615eucas1p1g; Thu, 30 Nov 2017 14:30:18 +0000 (GMT) X-AuditID: cbfec7f2-f793b6d000003243-6e-5a2015fa6c6f Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id B8.46.20118.AF5102A5; Thu, 30 Nov 2017 14:30:18 +0000 (GMT) Received: from AMDC2768.DIGITAL.local ([106.120.43.17]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P08005A4IYGHDA0@eusync3.samsung.com>; Thu, 30 Nov 2017 14:30:18 +0000 (GMT) From: Andrzej Hajda To: Wolfram Sang , Andi Shyti Cc: Andrzej Hajda , Bartlomiej Zolnierkiewicz , Marek Szyprowski , linux-i2c@vger.kernel.org (open list:I2C SUBSYSTEM), linux-samsung-soc@vger.kernel.org (moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES) Subject: [PATCH 2/3] i2c: exynos5: implement bus recovery functionality Date: Thu, 30 Nov 2017 15:30:06 +0100 Message-id: <20171130143007.30258-3-a.hajda@samsung.com> X-Mailer: git-send-email 2.15.0 In-reply-to: <20171130143007.30258-1-a.hajda@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCIsWRmVeSWpSXmKPExsWy7djP87q/RBWiDM7O0Le4te4cq8X2I89Y LTbOWM9q0fH3C6PFjPP7mCzWHrnLbrHyxCxmB3aPvi2rGD1OnnrC4vF5k1wAcxSXTUpqTmZZ apG+XQJXxs3HNgV3JSsezlnG1sC4RbSLkZNDQsBEYsq0PewQtpjEhXvr2UBsIYGljBJfHtd3 MXIB2Z8ZJR5+uc4G0/D88l5GiMQyoKL/b5ghOv4zSuydnQRiswloSvzdfBOsQUTAU+LW5xYW kAZmgQVMEi9u94AlhAXcJfZN6mACsVkEVCWWfX4GNohXwELidv9aVoht8hKLv+8Eq+cUsJTY NHsR2CAJgUY2ifZlC5ghilwk1j5tgbKFJV4d3wL1j4zE5cndUA3djBKf+k+wQzhTGCX+fZgB 1WEtcfj4RbB1zAJ8EpO2TQeKcwDFeSU62oQgSjwkjndPhxrqKHFt2iOo/3sYJS4/OsI4gVF6 ASPDKkaR1NLi3PTUYmO94sTc4tK8dL3k/NxNjMC4PP3v+KcdjF9PWB1iFOBgVOLhtRBUiBJi TSwrrsw9xCjBwawkwqt8Qj5KiDclsbIqtSg/vqg0J7X4EKM0B4uSOK9tVFukkEB6Yklqdmpq QWoRTJaJg1OqgbF+0+//pu9iSvuDN71VzmxrkDRMiRYWv6AusvbtrlmZfz9/DPm+ef0OhQr3 RQIGs64c8WnrzBFVVc679/207xG3mR85OlceeNBzqrNi2jtFnTPXlxTERK4puyg0V9Xq2dzK Ze+z41Z3ThZykOCSL0s0yWi4mnCp5FLssu6PgU9Smpm/7Mz4e1OJpTgj0VCLuag4EQBh/UIR xwIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupgluLIzCtJLcpLzFFi42I5/e/4Vd1fogpRBlebRC1urTvHarH9yDNW i40z1rNadPz9wmgx4/w+Jou1R+6yW6w8MYvZgd2jb8sqRo+Tp56weHzeJBfAHMVlk5Kak1mW WqRvl8CVcfOxTcFdyYqHc5axNTBuEe1i5OSQEDCReH55LyOELSZx4d56ti5GLg4hgSWMEt+v nGGBcBqZJBomHWQHqWIT0JT4u/kmG4gtIuApcetzC1gRs8AiJomzXXvBioQF3CX2TepgArFZ BFQlln1+xgxi8wpYSNzuX8sKsU5eYvH3nWCDOAUsJTbNXgQ0iANom4XEy9eCExh5FzAyrGIU SS0tzk3PLTbSK07MLS7NS9dLzs/dxAgMn23Hfm7Zwdj1LvgQowAHoxIPr4WgQpQQa2JZcWXu IUYJDmYlEV7lE/JRQrwpiZVVqUX58UWlOanFhxilOViUxHl796yOFBJITyxJzU5NLUgtgsky cXBKNTBm3Wni2Dq7/Hj0ssvWiy91qGRcrJhhxdO9/P2Zu3qHb4Q6J2ckXv9mUmlgszlO8863 m9nm/NeyPvhKP+C4d77kQy+zPX/+u5D7aYc3lE3LYArlsTXTjXw7I3lh2y/33nSnS9ICz/O1 bjYfYsnREJq/dbnhha/PFlWwi+l7Ll+5y0CxdlOcfo8SS3FGoqEWc1FxIgCLZ6aoGwIAAA== X-CMS-MailID: 20171130143018eucas1p13bd2ce9263f9ac016ab3b779920b512e X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20171130143018eucas1p13bd2ce9263f9ac016ab3b779920b512e X-RootMTR: 20171130143018eucas1p13bd2ce9263f9ac016ab3b779920b512e References: <20171130143007.30258-1-a.hajda@samsung.com> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In some circumstances I2C clients can be in abnormal state, to allow recover them from it I2C master can pulse SCL line until SDA line goes up and then generate STOP condition. Exynos driver does not have possibility to manipulate I2C lines directly, but it can provide similar functionality using manual commands. Replacing I2C adapter reset with bus recovery significantly incereases I2C bus robustness in case of timeouts. Signed-off-by: Andrzej Hajda --- drivers/i2c/busses/i2c-exynos5.c | 44 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index b02428498f6d..4ca43980e2ed 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -128,6 +128,10 @@ #define HSI2C_TIMEOUT_EN (1u << 31) #define HSI2C_TIMEOUT_MASK 0xff +/* I2C_MANUAL_CMD register bits */ +#define HSI2C_CMD_READ_DATA (1u << 4) +#define HSI2C_CMD_SEND_STOP (1u << 2) + /* I2C_TRANS_STATUS register bits */ #define HSI2C_MASTER_BUSY (1u << 17) #define HSI2C_SLAVE_BUSY (1u << 16) @@ -613,6 +617,26 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) spin_unlock_irqrestore(&i2c->lock, flags); } +void exynos5_i2c_recovery(struct exynos5_i2c *i2c) +{ + u32 val; + + val = readl(i2c->regs + HSI2C_CTL) | HSI2C_RXCHON; + writel(val, i2c->regs + HSI2C_CTL); + val = readl(i2c->regs + HSI2C_CONF) & ~HSI2C_AUTO_MODE; + writel(val, i2c->regs + HSI2C_CONF); + + writel(HSI2C_CMD_READ_DATA, i2c->regs + HSI2C_MANUAL_CMD); + exynos5_i2c_wait_bus_idle(i2c); + writel(HSI2C_CMD_SEND_STOP, i2c->regs + HSI2C_MANUAL_CMD); + exynos5_i2c_wait_bus_idle(i2c); + + val = readl(i2c->regs + HSI2C_CTL) & ~HSI2C_RXCHON; + writel(val, i2c->regs + HSI2C_CTL); + val = readl(i2c->regs + HSI2C_CONF) | HSI2C_AUTO_MODE; + writel(val, i2c->regs + HSI2C_CONF); +} + static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c, struct i2c_msg *msgs, int stop) { @@ -642,7 +666,7 @@ static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c, ret = exynos5_i2c_wait_bus_idle(i2c); if (ret < 0) { - exynos5_i2c_reset(i2c); + exynos5_i2c_recovery(i2c); if (ret == -ETIMEDOUT) dev_warn(i2c->dev, "%s timeout\n", (msgs->flags & I2C_M_RD) ? "rx" : "tx"); @@ -703,6 +727,23 @@ static const struct i2c_algorithm exynos5_i2c_algorithm = { .functionality = exynos5_i2c_func, }; +int exynos5_i2c_recover_bus(struct i2c_adapter *adap) +{ + struct exynos5_i2c *i2c = adap->algo_data; + + i2c_lock_adapter(adap); + clk_enable(i2c->clk); + exynos5_i2c_recovery(i2c); + clk_disable(i2c->clk); + i2c_unlock_adapter(adap); + + return 0; +} + +static struct i2c_bus_recovery_info exynos5_i2c_recovery_info = { + .recover_bus = exynos5_i2c_recover_bus +}; + static int exynos5_i2c_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -773,6 +814,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev) goto err_clk; exynos5_i2c_reset(i2c); + i2c->adap.bus_recovery_info = &exynos5_i2c_recovery_info; ret = i2c_add_adapter(&i2c->adap); if (ret < 0)