From patchwork Tue Jul 19 21:06:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asmaa Mnebhi X-Patchwork-Id: 1658230 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LnWbn1r30z9s2R for ; Wed, 20 Jul 2022 07:06:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1oDuQR-00088A-Pn; Tue, 19 Jul 2022 21:06:39 +0000 Received: from mail-il-dmz.mellanox.com ([193.47.165.129] helo=mellanox.co.il) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1oDuQP-00086w-8H for kernel-team@lists.ubuntu.com; Tue, 19 Jul 2022 21:06:37 +0000 Received: from Internal Mail-Server by MTLPINE1 (envelope-from asmaa@mellanox.com) with SMTP; 20 Jul 2022 00:06:33 +0300 Received: from bu-vnc02.mtbu.labs.mlnx (bu-vnc02.mtbu.labs.mlnx [10.15.2.65]) by mtbu-labmailer.labs.mlnx (8.14.4/8.14.4) with ESMTP id 26JL6WPT003048; Tue, 19 Jul 2022 17:06:32 -0400 Received: (from asmaa@localhost) by bu-vnc02.mtbu.labs.mlnx (8.14.7/8.13.8/Submit) id 26JL6W4L007945; Tue, 19 Jul 2022 17:06:32 -0400 From: Asmaa Mnebhi To: kernel-team@lists.ubuntu.com Subject: [SRU][F:linux-bluefield][PATCH v2 1/1] UBUNTU: SAUCE: i2c-mlxbf.c: support lock mechanism Date: Tue, 19 Jul 2022 17:06:21 -0400 Message-Id: <20220719210621.7895-2-asmaa@nvidia.com> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20220719210621.7895-1-asmaa@nvidia.com> References: <20220719210621.7895-1-asmaa@nvidia.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: asmaa@nvidia.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" Buglink: https://bugs.launchpad.net/bugs/1981105 Support the I2C lock mechanism, otherwise there could be unexpected behavior when an i2c bus is accessed by several entities like the linux driver, ATF driver and UEFI driver. Make sure to pick up the ATF/UEFI image to accompany this change because at boot time ATF will ensure that the lock is released. Signed-off-by: Asmaa Mnebhi --- drivers/i2c/busses/i2c-mlxbf.c | 38 ++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index 0ac9e70244a7..fcb5bb587df1 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c @@ -340,7 +340,8 @@ enum { * Timeout is given in microsends. Note also that timeout handling is not * exact. */ -#define SMBUS_TIMEOUT (300 * 1000) /* 300ms */ +#define SMBUS_TIMEOUT (300 * 1000) /* 300ms */ +#define SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */ /* Encapsulates timing parameters */ struct mlx_i2c_timings { @@ -573,6 +574,25 @@ static bool mlx_smbus_master_wait_for_idle(struct mlx_i2c_priv *priv) return false; } +/* + * wait for the lock to be released before acquiring it. + */ +static bool mlx_smbus_master_lock(struct mlx_i2c_priv *priv) +{ + if (mlx_smbus_poll(priv->smbus->io, SMBUS_MASTER_GW, + 1 << MASTER_LOCK_BIT_OFF, true, + SMBUS_LOCK_POLL_TIMEOUT)) + return true; + + return false; +} + +static void mlx_smbus_master_unlock(struct mlx_i2c_priv *priv) +{ + /* Clear the gw to clear the lock */ + writel(0, priv->smbus->io + SMBUS_MASTER_GW); +} + /* * Poll SMBus master status and return transaction status, * i.e. whether succeeded or failed. I2C and SMBus fault codes @@ -704,7 +724,7 @@ static int mlx_smbus_enable(struct mlx_i2c_priv *priv, u8 slave, /* Clear status bits */ smbus_write(priv->smbus->io, SMBUS_MASTER_STATUS, 0x0); /* Set the cause data */ - smbus_write(priv->smbus->io, I2C_CAUSE_OR_CLEAR_BITS, ~0x0); + smbus_write(priv->mst_cause->io, I2C_CAUSE_OR_CLEAR_BITS, ~0x0); /* Zero PEC byte */ smbus_write(priv->smbus->io, SMBUS_MASTER_PEC, 0x0); /* Zero byte count */ @@ -744,7 +764,13 @@ static int mlx_smbus_start_transaction(struct mlx_i2c_priv *priv, slave = request->slave & 0x7f; addr = slave << 1; - /* First of all, check whether the HW is idle */ + /* Try to acquire the smbus gw lock before any reads of the GW register since + * a read sets the lock. + */ + if (WARN_ON(!mlx_smbus_master_lock(priv))) + return -EBUSY; + + /* Check whether the HW is idle */ if (WARN_ON(!mlx_smbus_master_wait_for_idle(priv))) return -EBUSY; @@ -802,8 +828,10 @@ static int mlx_smbus_start_transaction(struct mlx_i2c_priv *priv, if (write_en) { ret = mlx_smbus_enable(priv, slave, write_len, block_en, pec_en, 0); - if (ret != 0) + if (ret) { + mlx_smbus_master_unlock(priv); return ret; + } } if (read_en) { @@ -830,6 +858,8 @@ static int mlx_smbus_start_transaction(struct mlx_i2c_priv *priv, SMBUS_MASTER_FSM_PS_STATE_MASK); } + mlx_smbus_master_unlock(priv); + return ret; }