From patchwork Mon Oct 24 11:28:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 9658 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp534430wru; Mon, 24 Oct 2022 09:11:05 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4U+tH41m/yt++cNF08PyGa+b2R0R/a1XSKr7zp3LYWOq7WlI7MiBi+EDjYiFZJDXjNkwI5 X-Received: by 2002:a17:906:eec9:b0:73d:c369:690f with SMTP id wu9-20020a170906eec900b0073dc369690fmr28397857ejb.767.1666627855016; Mon, 24 Oct 2022 09:10:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666627855; cv=none; d=google.com; s=arc-20160816; b=oasmLudAbuXzYuUCqA/26WLxy38X0rcTH5+35q8RLG6u65scAWLEMT6hvtpUREaXYt gxy0LWJEyzOig1NM45H1BnrpjUS5jPCNTnBFPJbfAoUjaKgW0k56VQLRvDwgt0SITLJh eKBICG/vb/twnRT5+jtPbuIxMfyX2Gz7iWArDBHCNB1usTgQjASLheDdjHf3Lr3B4mNk J7zsoS+Kf2LTG4P76I9FikWiS7D+yEGcvpGxzJmBcV8i9fcQJkBW/QFq5OBDdmWHCEQO S3bwAQMmtLyiAHO7rja6pr2OqSbEUbU8bck3zm9yUIcK1VjMxzSy4Su+dO07EzTZ6+lJ tRLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=cGQA4ImMPEGgVI2jDJxc7Taf/yeL20Ha6qYZoT3IMQU=; b=TNQ/ffFAca2iqKgQfmds3Kn+qLmI0qLfqwYH6whxsQ5vI7oiPAYBEY0oNWWxEm9tW+ 3NPCsx3KNiYO6377dkTeJYVB2E0fGjMRbAaeO0hM1BuNHE8h/mFa2svl5iYqF6KuKC7X eRpZRXTEP+sl7HJh7/vDTP1dnddX7o3+0hSA37lsjh0x1OJBZVtx1iuSUAmHPDa4ASR4 UEUCVSLlAqvDyVQJxoCb/P7JFEWzQvBnrGbT8yf8R50e/KMfgyt06sQcVrK8KuynOc2l HfXYi2FFhsu4l1/jcyAw3owJHfYnFPLMKMiwFiC7x4aDKww8gevijYNPd4eRPWCxo21q n6fA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=F51Tx4Fw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e19-20020a17090658d300b0078da3cd3073si137924ejs.628.2022.10.24.09.10.30; Mon, 24 Oct 2022 09:10:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=F51Tx4Fw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233470AbiJXQIh (ORCPT + 99 others); Mon, 24 Oct 2022 12:08:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233493AbiJXQEp (ORCPT ); Mon, 24 Oct 2022 12:04:45 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BA0811D9BD; Mon, 24 Oct 2022 07:57:15 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 789B1B81610; Mon, 24 Oct 2022 12:21:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAE02C433D6; Mon, 24 Oct 2022 12:21:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666614082; bh=0jfWPenfL/oG5oJ9Lg9hxmiwRpgO6UV80eJbmRUMs0E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F51Tx4FwxmC1bZC8kYCgJ6+3d0k3epjCpi68QZg8edTpzjk7jdyx4IRDMr1/RnGvy 2FSsg/o7svXnFZFeNSbH+caRE3rBlfEwuzHvlYt1yuo6aktGfJQNTJVbCigoaVkrUk Yc/SVK/xrC890j+u5virtrcLJL4ImE7fNHkc4xU8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Khalil Blaiech , Asmaa Mnebhi , Wolfram Sang , Sasha Levin Subject: [PATCH 5.10 126/390] i2c: mlxbf: support lock mechanism Date: Mon, 24 Oct 2022 13:28:43 +0200 Message-Id: <20221024113028.030483212@linuxfoundation.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221024113022.510008560@linuxfoundation.org> References: <20221024113022.510008560@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747585969887212973?= X-GMAIL-MSGID: =?utf-8?q?1747585969887212973?= From: Asmaa Mnebhi [ Upstream commit 86067ccfa1424a26491542d6f6d7546d40b61a10 ] Linux is not the only entity using the BlueField I2C busses so support a lock mechanism provided by hardware to avoid issues when multiple entities are trying to access the same bus. The lock is acquired whenever written explicitely or the lock register is read. So make sure it is always released at the end of a successful or failed transaction. Fixes: b5b5b32081cd206b (i2c: mlxbf: I2C SMBus driver for Mellanox BlueField SoC) Reviewed-by: Khalil Blaiech Signed-off-by: Asmaa Mnebhi Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-mlxbf.c | 44 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index bea82a787b4f..90c488a60693 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c @@ -312,6 +312,7 @@ static u64 mlxbf_i2c_corepll_frequency; * exact. */ #define MLXBF_I2C_SMBUS_TIMEOUT (300 * 1000) /* 300ms */ +#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */ /* Encapsulates timing parameters. */ struct mlxbf_i2c_timings { @@ -520,6 +521,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv) return false; } +/* + * wait for the lock to be released before acquiring it. + */ +static bool mlxbf_i2c_smbus_master_lock(struct mlxbf_i2c_priv *priv) +{ + if (mlxbf_smbus_poll(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW, + MLXBF_I2C_MASTER_LOCK_BIT, true, + MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT)) + return true; + + return false; +} + +static void mlxbf_i2c_smbus_master_unlock(struct mlxbf_i2c_priv *priv) +{ + /* Clear the gw to clear the lock */ + writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW); +} + static bool mlxbf_i2c_smbus_transaction_success(u32 master_status, u32 cause_status) { @@ -711,10 +731,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, slave = request->slave & GENMASK(6, 0); addr = slave << 1; - /* First of all, check whether the HW is idle. */ - if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) + /* + * Try to acquire the smbus gw lock before any reads of the GW register since + * a read sets the lock. + */ + if (WARN_ON(!mlxbf_i2c_smbus_master_lock(priv))) return -EBUSY; + /* Check whether the HW is idle */ + if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) { + ret = -EBUSY; + goto out_unlock; + } + /* Set first byte. */ data_desc[data_idx++] = addr; @@ -738,8 +767,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, write_en = 1; write_len += operation->length; if (data_idx + operation->length > - MLXBF_I2C_MASTER_DATA_DESC_SIZE) - return -ENOBUFS; + MLXBF_I2C_MASTER_DATA_DESC_SIZE) { + ret = -ENOBUFS; + goto out_unlock; + } memcpy(data_desc + data_idx, operation->buffer, operation->length); data_idx += operation->length; @@ -771,7 +802,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en, pec_en, 0); if (ret) - return ret; + goto out_unlock; } if (read_en) { @@ -798,6 +829,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM); } +out_unlock: + mlxbf_i2c_smbus_master_unlock(priv); + return ret; }