From patchwork Mon Sep 10 21:45:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jae Hyun Yoo X-Patchwork-Id: 10594795 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 633933E9D for ; Mon, 10 Sep 2018 21:47:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5153A28E9B for ; Mon, 10 Sep 2018 21:47:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4519E29250; Mon, 10 Sep 2018 21:47:26 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A3FC728E9B for ; Mon, 10 Sep 2018 21:47:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=p3q7vuThJM5vIdT6+t/IHkjxcmqrpNhctc1d3oD7K6Q=; b=ifvKcPyiYBMEfnUaiTFExI07pe XU3maPsZ1buwXqPP48J36qn988iUITRJANPhg+d7RQFcI5mKxWDdi1dS4i/WsTJWBvT1ZPEwgZVhK K6vdP6ipcIykl94vB65QpPjVYxseDWPd3N2wsTfF20fUZ0Og/tQvmhrgEeLTsJmGHiBteqZlvNNJM T7Jk1Az086mm6fyJJOhyNrGAEDSugfNLyzxWUfVjqMAD6dmfIDe5Y7mCOiI9FpQ24kgMRIfIQ9mgN OsJ7QTzCRrZSSqzXto5o64GN11vGZDm20O0QkUuOZbT2Qdg1V+YYbEdUrTarqAmorwcAe4hXsVM2k nFCnrmCQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fzU1a-0005t0-U7; Mon, 10 Sep 2018 21:47:14 +0000 Received: from mga14.intel.com ([192.55.52.115]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fzU0P-0005Kg-0s for linux-arm-kernel@lists.infradead.org; Mon, 10 Sep 2018 21:46:02 +0000 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Sep 2018 14:45:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,357,1531810800"; d="scan'208";a="256062310" Received: from maru.jf.intel.com ([10.54.51.80]) by orsmga005.jf.intel.com with ESMTP; 10 Sep 2018 14:45:36 -0700 From: Jae Hyun Yoo To: Brendan Higgins , Benjamin Herrenschmidt , Joel Stanley , Andrew Jeffery , linux-i2c@vger.kernel.org, openbmc@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH i2c-next 1/2] dt-bindings: i2c: aspeed: Add 'idle-wait-timeout-ms' setting Date: Mon, 10 Sep 2018 14:45:18 -0700 Message-Id: <20180910214519.14126-2-jae.hyun.yoo@linux.intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180910214519.14126-1-jae.hyun.yoo@linux.intel.com> References: <20180910214519.14126-1-jae.hyun.yoo@linux.intel.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180910_144601_107797_EE390B7C X-CRM114-Status: GOOD ( 12.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vernon Mauery , Jae Hyun Yoo , Jarkko Nikula , James Feist MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This commit adds 'idle-wait-timeout-ms' setting which can be used for bus idle waiting logic in multi-master environment. Signed-off-by: Jae Hyun Yoo --- Documentation/devicetree/bindings/i2c/i2c-aspeed.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt index 8fbd8633a387..42ecaaf67172 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt @@ -13,9 +13,13 @@ Required Properties: - interrupts : interrupt number Optional Properties: -- bus-frequency : frequency of the bus clock in Hz defaults to 100 kHz when not - specified -- multi-master : states that there is another master active on this bus. +- bus-frequency : frequency of the bus clock in Hz defaults to 100 kHz + when not specified +- multi-master : states that there is another master active on this + bus. +- idle-wait-timeout-ms : bus idle waiting timeout in milliseconds when + multi-master is set, defaults to 100 ms when not + specified. Example: From patchwork Mon Sep 10 21:45:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jae Hyun Yoo X-Patchwork-Id: 10594793 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 216EB112B for ; Mon, 10 Sep 2018 21:46:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F63A28E9B for ; Mon, 10 Sep 2018 21:46:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01FEE29250; Mon, 10 Sep 2018 21:46:47 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7F36A28E9B for ; Mon, 10 Sep 2018 21:46:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=1il91Rw7qa9GCO2FVCd7ETkU1IPCNS3D1aKb0BJvxl0=; b=igqPWlM663EHa0xfF/H22IgYd/ wWlfA78dTgMhsSp6O5xwHT8IT6LiGlz0a5zw+i6dw/DrHO7s5rvMLHEWp/H3tIsPH8wbPVgXQnzJm 26f0QVCUF7/NUrzUIsOLHB0Y65kARXuxrcxeeSHvnGdYNvGjrlxbQfLIp6OR7xsd3kEdzrhleOP/3 TRJeBayOTlenWda/zoU6RWbf7pMAlf8x/3b5LSPsDZu+S7dgPkjraPc/91WXB76sNVMs0XkiMEnAm EDdC4Jm2Cghh6pe0+YoE/MWoBaapavkzUKOdoE8YVc5dM50aUURkKjPsvNZxwqLLnxhRGA5VRocXR gYw0qjFA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fzU0t-0005Yj-Fa; Mon, 10 Sep 2018 21:46:31 +0000 Received: from mga03.intel.com ([134.134.136.65]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fzU0N-0005Kh-NB for linux-arm-kernel@lists.infradead.org; Mon, 10 Sep 2018 21:46:01 +0000 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Sep 2018 14:45:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,357,1531810800"; d="scan'208";a="256062314" Received: from maru.jf.intel.com ([10.54.51.80]) by orsmga005.jf.intel.com with ESMTP; 10 Sep 2018 14:45:38 -0700 From: Jae Hyun Yoo To: Brendan Higgins , Benjamin Herrenschmidt , Joel Stanley , Andrew Jeffery , linux-i2c@vger.kernel.org, openbmc@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH i2c-next 2/2] i2c: aspeed: Add bus idle waiting logic for multi-master use cases Date: Mon, 10 Sep 2018 14:45:19 -0700 Message-Id: <20180910214519.14126-3-jae.hyun.yoo@linux.intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180910214519.14126-1-jae.hyun.yoo@linux.intel.com> References: <20180910214519.14126-1-jae.hyun.yoo@linux.intel.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180910_144559_829771_863293ED X-CRM114-Status: GOOD ( 20.11 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vernon Mauery , Jae Hyun Yoo , Jarkko Nikula , James Feist MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP In multi-master environment, this driver side master cannot know exactly when peer master sends data to this side master so a case can be happened that this master tries to send data through the master_xfer function but slave data from peer master is still being processed by this driver. To prevent state corruption in the case, this patch adds checking if any slave operation is ongoing and it wait up to the timeout duration before starting a master_xfer operation. Signed-off-by: Jae Hyun Yoo --- drivers/i2c/busses/i2c-aspeed.c | 70 ++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index c258c4d9a4c0..73359eda98be 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -99,6 +100,7 @@ ASPEED_I2CD_INTR_TX_ACK) /* 0x14 : I2CD Command/Status Register */ +#define ASPEED_I2CD_XFER_MODE_STS_MASK GENMASK(22, 19) #define ASPEED_I2CD_SCL_LINE_STS BIT(18) #define ASPEED_I2CD_SDA_LINE_STS BIT(17) #define ASPEED_I2CD_BUS_BUSY_STS BIT(16) @@ -115,6 +117,10 @@ /* 0x18 : I2CD Slave Device Address Register */ #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0) +/* Timeout for bus busy checking */ +#define ASPEED_I2CD_IDLE_WAIT_TIMEOUT_MS_DEFAULT 100 /* 100 ms */ +#define ASPEED_I2CD_BUS_BUSY_CHECK_INTERVAL_US 10000 /* 10 ms */ + enum aspeed_i2c_master_state { ASPEED_I2C_MASTER_INACTIVE, ASPEED_I2C_MASTER_START, @@ -155,6 +161,9 @@ struct aspeed_i2c_bus { int cmd_err; /* Protected only by i2c_lock_bus */ int master_xfer_result; + /* Multi-master */ + bool multi_master; + u32 idle_wait_timeout_ms; #if IS_ENABLED(CONFIG_I2C_SLAVE) struct i2c_client *slave; enum aspeed_i2c_slave_state slave_state; @@ -590,27 +599,49 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) return irq_remaining ? IRQ_NONE : IRQ_HANDLED; } +static int aspeed_i2c_check_bus_busy(struct aspeed_i2c_bus *bus) +{ + u32 status_check_mask = ASPEED_I2CD_BUS_BUSY_STS; + ktime_t timeout; + + if (bus->multi_master) { + might_sleep(); + timeout = ktime_add_ms(ktime_get(), bus->idle_wait_timeout_ms); + /* + * ASPEED_I2CD_XFER_MODE_STS_MASK is marked as + * 'for debugging purpose only' in datasheet but ASPEED + * confirmed that this reflects real information and good to be + * used in practical code. It will be used only in multi-master + * use cases. + */ + status_check_mask |= ASPEED_I2CD_XFER_MODE_STS_MASK; + } + + for (;;) { + if (!(readl(bus->base + ASPEED_I2C_CMD_REG) & + status_check_mask)) + return 0; + if (!bus->multi_master) + break; + if (ktime_compare(ktime_get(), timeout) > 0) + break; + usleep_range((ASPEED_I2CD_BUS_BUSY_CHECK_INTERVAL_US >> 2) + 1, + ASPEED_I2CD_BUS_BUSY_CHECK_INTERVAL_US); + } + + return aspeed_i2c_recover_bus(bus); +} + static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap); unsigned long time_left, flags; - int ret = 0; - - spin_lock_irqsave(&bus->lock, flags); - bus->cmd_err = 0; - /* If bus is busy, attempt recovery. We assume a single master - * environment. - */ - if (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS) { - spin_unlock_irqrestore(&bus->lock, flags); - ret = aspeed_i2c_recover_bus(bus); - if (ret) - return ret; - spin_lock_irqsave(&bus->lock, flags); - } + if (aspeed_i2c_check_bus_busy(bus)) + return -EAGAIN; + spin_lock_irqsave(&bus->lock, flags); bus->cmd_err = 0; bus->msgs = msgs; bus->msgs_index = 0; @@ -798,8 +829,17 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, if (ret < 0) return ret; - if (!of_property_read_bool(pdev->dev.of_node, "multi-master")) + if (of_property_read_bool(pdev->dev.of_node, "multi-master")) { + bus->multi_master = true; + ret = of_property_read_u32(pdev->dev.of_node, + "idle-wait-timeout-ms", + &bus->idle_wait_timeout_ms); + if (ret) + bus->idle_wait_timeout_ms = + ASPEED_I2CD_IDLE_WAIT_TIMEOUT_MS_DEFAULT; + } else { fun_ctrl_reg |= ASPEED_I2CD_MULTI_MASTER_DIS; + } /* Enable Master Mode */ writel(readl(bus->base + ASPEED_I2C_FUN_CTRL_REG) | fun_ctrl_reg,