public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Asmaa Mnebhi <asmaa@nvidia.com>
To: Wolfram Sang <wsa+renesas@sang-engineering.com>,
	linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Asmaa Mnebhi <asmaa@nvidia.com>, Khalil Blaiech <kblaiech@nvidia.com>
Subject: [PATCH v1 7/7] i2c-mlxbf.c: support lock mechanism
Date: Tue, 16 Aug 2022 18:54:12 -0400	[thread overview]
Message-ID: <20220816225412.9095-8-asmaa@nvidia.com> (raw)
In-Reply-To: <20220816225412.9095-1-asmaa@nvidia.com>

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.

Reviewed-by: Khalil Blaiech <kblaiech@nvidia.com>
Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
---
 drivers/i2c/busses/i2c-mlxbf.c | 42 ++++++++++++++++++++++++++++++----
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c
index cc87c2511678..aa0ea41e7bfd 100644
--- a/drivers/i2c/busses/i2c-mlxbf.c
+++ b/drivers/i2c/busses/i2c-mlxbf.c
@@ -296,6 +296,7 @@
  * exact.
  */
 #define MLXBF_I2C_SMBUS_TIMEOUT   (300 * 1000) /* 300ms */
+#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */
 
 /* Polling frequency in microseconds. */
 #define MLXBF_I2C_POLL_FREQ_IN_USEC        200
@@ -523,6 +524,25 @@ static bool mlxbf_i2c_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_i2c_poll(priv->mst->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->mst->io + MLXBF_I2C_SMBUS_MASTER_GW);
+}
+
 static bool mlxbf_i2c_smbus_transaction_success(u32 master_status,
 						u32 cause_status)
 {
@@ -725,10 +745,18 @@ 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_i2c_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_i2c_smbus_master_wait_for_idle(priv))) {
+		mlxbf_i2c_smbus_master_unlock(priv);
+		return -EBUSY;
+	}
+
 	/* Set first byte. */
 	data_desc[data_idx++] = addr;
 
@@ -752,8 +780,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)
+					MLXBF_I2C_MASTER_DATA_DESC_SIZE) {
+				mlxbf_i2c_smbus_master_unlock(priv);
 				return -ENOBUFS;
+			}
 			memcpy(data_desc + data_idx,
 			       operation->buffer, operation->length);
 			data_idx += operation->length;
@@ -784,8 +814,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
 	if (write_en) {
 		ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en,
 					 pec_en, 0);
-		if (ret)
+		if (ret) {
+			mlxbf_i2c_smbus_master_unlock(priv);
 			return ret;
+		}
 	}
 
 	if (read_en) {
@@ -812,6 +844,8 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
 			priv->mst->io + priv->chip->smbus_master_fsm_off);
 	}
 
+	mlxbf_i2c_smbus_master_unlock(priv);
+
 	return ret;
 }
 
-- 
2.30.1


  parent reply	other threads:[~2022-08-16 23:01 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-16 22:54 [PATCH v1 0/7] i2c-mlxbf.c: bug fixes and new feature support Asmaa Mnebhi
2022-08-16 22:54 ` [PATCH v1 1/7] i2c-mlxbf.c: Fix frequency calculation Asmaa Mnebhi
2022-08-16 22:54 ` [PATCH v1 2/7] i2c-mlxbf.c: remove IRQF_ONESHOT Asmaa Mnebhi
2022-08-16 22:54 ` [PATCH v1 3/7] i2c-mlxbf: add multi slave functionality Asmaa Mnebhi
2022-08-18 16:25   ` Wolfram Sang
2022-08-18 16:41     ` Asmaa Mnebhi
2022-08-16 22:54 ` [PATCH v1 4/7] i2c-mlxbf.c: incorrect base address passed during io write Asmaa Mnebhi
2022-08-18 16:27   ` Wolfram Sang
2022-08-18 16:40     ` Asmaa Mnebhi
2022-08-18 17:21       ` Asmaa Mnebhi
2022-08-18 20:24         ` Wolfram Sang
2022-08-18 20:30           ` Asmaa Mnebhi
2022-08-16 22:54 ` [PATCH v1 5/7] i2c-mlxbf: prevent stack overflow in mlxbf_i2c_smbus_start_transaction() Asmaa Mnebhi
2022-08-16 22:54 ` [PATCH v1 6/7] i2c-mlxbf.c: support BlueField-3 SoC Asmaa Mnebhi
2022-08-18 15:11   ` Rob Herring
2022-08-18 20:43     ` Asmaa Mnebhi
2022-08-16 22:54 ` Asmaa Mnebhi [this message]
2022-08-18 16:24 ` [PATCH v1 0/7] i2c-mlxbf.c: bug fixes and new feature support Wolfram Sang
2022-08-18 16:42   ` Asmaa Mnebhi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220816225412.9095-8-asmaa@nvidia.com \
    --to=asmaa@nvidia.com \
    --cc=kblaiech@nvidia.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox