linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes
@ 2025-04-15 15:36 Sven Peter via B4 Relay
  2025-04-15 15:36 ` [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include Sven Peter via B4 Relay
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:36 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter, Andy Shevchenko

Hi,

This series adds a few fixes/improvements to the error recovery for
Apple/PASemi i2c controllers.
The patches have been in our downstream tree and were originally used
to debug a rare glitch caused by clock strechting but are useful in
general. We haven't seen the controller misbehave since adding these.

Best,

Sven

Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
Changes in v2:
- Added commit to use the correct include (bits.h instead of bitfield.h)
- Added commit to sort includes
- Moved timeout explanations to code instead of just the commit log
- Made timeout recovery also work correctly in the interrupt case when
  waiting for the condition failed
- Used readx_poll_timeout instead of open-coded alternative
- Link to v1: https://lore.kernel.org/r/20250222-pasemi-fixes-v1-0-d7ea33d50c5e@svenpeter.dev

---
Hector Martin (3):
      i2c: pasemi: Improve error recovery
      i2c: pasemi: Enable the unjam machine
      i2c: pasemi: Log bus reset causes

Sven Peter (3):
      i2c: pasemi: Use correct bits.h include
      i2c: pasemi: Sort includes alphabetically
      i2c: pasemi: Improve timeout handling

 drivers/i2c/busses/i2c-pasemi-core.c | 114 ++++++++++++++++++++++++++++-------
 drivers/i2c/busses/i2c-pasemi-pci.c  |  10 +--
 2 files changed, 96 insertions(+), 28 deletions(-)
---
base-commit: 0af2f6be1b4281385b618cb86ad946eded089ac8
change-id: 20250220-pasemi-fixes-916cb77404ba

Best regards,
-- 
Sven Peter <sven@svenpeter.dev>




^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
@ 2025-04-15 15:36 ` Sven Peter via B4 Relay
  2025-04-15 17:10   ` Alyssa Rosenzweig
  2025-04-15 15:36 ` [PATCH v2 2/6] i2c: pasemi: Sort includes alphabetically Sven Peter via B4 Relay
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:36 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter, Andy Shevchenko

From: Sven Peter <sven@svenpeter.dev>

When changing the #defines to use BIT and GENMASK the bitfield.h include
was added instead of the correct bits.h include.

Reported-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Closes: https://lore.kernel.org/asahi/Z965tVhC5jxy1kqZ@surfacebook.localdomain/
Fixes: 8b4da3ef9206 ("i2c: pasemi: Add registers bits and switch to BIT()")
Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index bd128ab2e2ebb64929f2f6a3525835a880c3114d..71cc8cfc7c5cbf3924269f6217712d42008c03ff 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -5,7 +5,7 @@
  * SMBus host driver for PA Semi PWRficient
  */
 
-#include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>

-- 
2.34.1




^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/6] i2c: pasemi: Sort includes alphabetically
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
  2025-04-15 15:36 ` [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include Sven Peter via B4 Relay
@ 2025-04-15 15:36 ` Sven Peter via B4 Relay
  2025-04-15 17:11   ` Alyssa Rosenzweig
  2025-04-15 15:36 ` [PATCH v2 3/6] i2c: pasemi: Improve timeout handling Sven Peter via B4 Relay
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:36 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter

From: Sven Peter <sven@svenpeter.dev>

No functional changes.

Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 10 +++++-----
 drivers/i2c/busses/i2c-pasemi-pci.c  | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index 71cc8cfc7c5cbf3924269f6217712d42008c03ff..df1b0087dcacb0a3b94196368137d5e20b0e6d7e 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -6,15 +6,15 @@
  */
 
 #include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
 #include <linux/sched.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/io.h>
+#include <linux/stddef.h>
 
 #include "i2c-pasemi-core.h"
 
diff --git a/drivers/i2c/busses/i2c-pasemi-pci.c b/drivers/i2c/busses/i2c-pasemi-pci.c
index 77f90c7436eda2df16afd7f1cac79355fb005bfd..b9ccb54ec77e22bb1b77848c858e2e0cc51db7e3 100644
--- a/drivers/i2c/busses/i2c-pasemi-pci.c
+++ b/drivers/i2c/busses/i2c-pasemi-pci.c
@@ -5,15 +5,15 @@
  * SMBus host driver for PA Semi PWRficient
  */
 
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
 #include <linux/sched.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/io.h>
+#include <linux/stddef.h>
 
 #include "i2c-pasemi-core.h"
 

-- 
2.34.1




^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/6] i2c: pasemi: Improve timeout handling
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
  2025-04-15 15:36 ` [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include Sven Peter via B4 Relay
  2025-04-15 15:36 ` [PATCH v2 2/6] i2c: pasemi: Sort includes alphabetically Sven Peter via B4 Relay
@ 2025-04-15 15:36 ` Sven Peter via B4 Relay
  2025-04-15 17:11   ` Alyssa Rosenzweig
  2025-04-17 12:57   ` Andi Shyti
  2025-04-15 15:36 ` [PATCH v2 4/6] i2c: pasemi: Improve error recovery Sven Peter via B4 Relay
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:36 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter

From: Sven Peter <sven@svenpeter.dev>

Add proper timeout handling for the interrupt path.
Previously, this was only correctly done for the polling path.
Note that we drop reg_write(smbus, REG_SMSTA, status) here which
will be done anyway whenever the next transaction starts via
pasemi_smb_clear.

Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index df1b0087dcacb0a3b94196368137d5e20b0e6d7e..9b611dbdfef23e78a4ea75ac0311938d52b6ba96 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -91,32 +91,42 @@ static void pasemi_smb_clear(struct pasemi_smbus *smbus)
 static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
 {
 	int timeout = 100;
+	int ret;
 	unsigned int status;
 
 	if (smbus->use_irq) {
 		reinit_completion(&smbus->irq_completion);
 		reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
-		wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
+		ret = wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
 		reg_write(smbus, REG_IMASK, 0);
 		status = reg_read(smbus, REG_SMSTA);
+
+		if (ret < 0) {
+			dev_err(smbus->dev,
+				"Completion wait failed with %d, status 0x%08x\n",
+				ret, status);
+			return ret;
+		} else if (ret == 0) {
+			dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
+			return -ETIME;
+		}
 	} else {
 		status = reg_read(smbus, REG_SMSTA);
 		while (!(status & SMSTA_XEN) && timeout--) {
 			msleep(1);
 			status = reg_read(smbus, REG_SMSTA);
 		}
+
+		if (timeout < 0) {
+			dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
+			return -ETIME;
+		}
 	}
 
 	/* Got NACK? */
 	if (status & SMSTA_MTN)
 		return -ENXIO;
 
-	if (timeout < 0) {
-		dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
-		reg_write(smbus, REG_SMSTA, status);
-		return -ETIME;
-	}
-
 	/* Clear XEN */
 	reg_write(smbus, REG_SMSTA, SMSTA_XEN);
 

-- 
2.34.1




^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 4/6] i2c: pasemi: Improve error recovery
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
                   ` (2 preceding siblings ...)
  2025-04-15 15:36 ` [PATCH v2 3/6] i2c: pasemi: Improve timeout handling Sven Peter via B4 Relay
@ 2025-04-15 15:36 ` Sven Peter via B4 Relay
  2025-04-15 17:12   ` Alyssa Rosenzweig
  2025-04-17 13:07   ` Andi Shyti
  2025-04-15 15:36 ` [PATCH v2 5/6] i2c: pasemi: Enable the unjam machine Sven Peter via B4 Relay
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:36 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter

From: Hector Martin <marcan@marcan.st>

The hardware (supposedly) has a 25ms timeout for clock stretching
and the driver uses 100ms which should be plenty. The error
reocvery itself is however lacking.

Add handling for all the missing error condition, and better recovery in
pasemi_smb_clear(). Also move the timeout to a #define since it's used
in multiple places now.

Signed-off-by: Hector Martin <marcan@marcan.st>
[sven: adjusted commit message after splitting the commit into two]
Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 75 +++++++++++++++++++++++++++++++-----
 1 file changed, 65 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index 9b611dbdfef23e78a4ea75ac0311938d52b6ba96..2f31f039bedfd7f78d6572fe925125b1a6d0724b 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -52,6 +53,12 @@
 #define CTL_UJM		BIT(8)
 #define CTL_CLK_M	GENMASK(7, 0)
 
+/*
+ * The hardware (supposedly) has a 25ms timeout for clock stretching, thus
+ * use 100ms here which should be plenty.
+ */
+#define TRANSFER_TIMEOUT_MS	100
+
 static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
 {
 	dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val);
@@ -80,24 +87,44 @@ static void pasemi_reset(struct pasemi_smbus *smbus)
 	reinit_completion(&smbus->irq_completion);
 }
 
-static void pasemi_smb_clear(struct pasemi_smbus *smbus)
+static int pasemi_smb_clear(struct pasemi_smbus *smbus)
 {
 	unsigned int status;
+	int ret;
 
-	status = reg_read(smbus, REG_SMSTA);
+	/* First wait for the bus to go idle */
+	ret = readx_poll_timeout(ioread32, smbus->ioaddr + REG_SMSTA,
+				 status, !(status & (SMSTA_XIP | SMSTA_JAM)),
+				 USEC_PER_MSEC, USEC_PER_MSEC * TRANSFER_TIMEOUT_MS);
+
+	if (ret < 0) {
+		dev_err(smbus->dev, "Bus is still stuck (status 0x%08x)\n", status);
+		return -EIO;
+	}
+
+	/* If any badness happened or there is data in the FIFOs, reset the FIFOs */
+	if ((status & (SMSTA_MRNE | SMSTA_JMD | SMSTA_MTO | SMSTA_TOM | SMSTA_MTN | SMSTA_MTA)) ||
+	    !(status & SMSTA_MTE))
+		pasemi_reset(smbus);
+
+	/* Clear the flags */
 	reg_write(smbus, REG_SMSTA, status);
+
+	return 0;
 }
 
 static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
 {
-	int timeout = 100;
+	int timeout = TRANSFER_TIMEOUT_MS;
 	int ret;
 	unsigned int status;
 
 	if (smbus->use_irq) {
 		reinit_completion(&smbus->irq_completion);
-		reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
-		ret = wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
+		/* XEN should be set when a transaction terminates, whether due to error or not */
+		reg_write(smbus, REG_IMASK, SMSTA_XEN);
+		ret = wait_for_completion_timeout(&smbus->irq_completion,
+						  msecs_to_jiffies(timeout));
 		reg_write(smbus, REG_IMASK, 0);
 		status = reg_read(smbus, REG_SMSTA);
 
@@ -123,9 +150,35 @@ static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
 		}
 	}
 
+	/* Controller timeout? */
+	if (status & SMSTA_TOM) {
+		dev_warn(smbus->dev, "Controller timeout, status 0x%08x\n", status);
+		return -EIO;
+	}
+
+	/* Peripheral timeout? */
+	if (status & SMSTA_MTO) {
+		dev_warn(smbus->dev, "Peripheral timeout, status 0x%08x\n", status);
+		return -ETIME;
+	}
+
+	/* Still stuck in a transaction? */
+	if (status & SMSTA_XIP) {
+		dev_warn(smbus->dev, "Bus stuck, status 0x%08x\n", status);
+		return -EIO;
+	}
+
+	/* Arbitration loss? */
+	if (status & SMSTA_MTA) {
+		dev_warn(smbus->dev, "Arbitration loss, status 0x%08x\n", status);
+		return -EBUSY;
+	}
+
 	/* Got NACK? */
-	if (status & SMSTA_MTN)
+	if (status & SMSTA_MTN) {
+		dev_warn(smbus->dev, "NACK, status 0x%08x\n", status);
 		return -ENXIO;
+	}
 
 	/* Clear XEN */
 	reg_write(smbus, REG_SMSTA, SMSTA_XEN);
@@ -187,9 +240,9 @@ static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
 	struct pasemi_smbus *smbus = adapter->algo_data;
 	int ret, i;
 
-	pasemi_smb_clear(smbus);
-
-	ret = 0;
+	ret = pasemi_smb_clear(smbus);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < num && !ret; i++)
 		ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
@@ -210,7 +263,9 @@ static int pasemi_smb_xfer(struct i2c_adapter *adapter,
 	addr <<= 1;
 	read_flag = read_write == I2C_SMBUS_READ;
 
-	pasemi_smb_clear(smbus);
+	err = pasemi_smb_clear(smbus);
+	if (err)
+		return err;
 
 	switch (size) {
 	case I2C_SMBUS_QUICK:

-- 
2.34.1




^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 5/6] i2c: pasemi: Enable the unjam machine
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
                   ` (3 preceding siblings ...)
  2025-04-15 15:36 ` [PATCH v2 4/6] i2c: pasemi: Improve error recovery Sven Peter via B4 Relay
@ 2025-04-15 15:36 ` Sven Peter via B4 Relay
  2025-04-15 15:37 ` [PATCH v2 6/6] i2c: pasemi: Log bus reset causes Sven Peter via B4 Relay
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:36 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter

From: Hector Martin <marcan@marcan.st>

The I2C bus can get stuck under some conditions (desync between
controller and device). The pasemi controllers include an unjam feature
that is enabled on reset, but was being disabled by the driver. Keep it
enabled by explicitly setting the UJM bit in the CTL register. This
should help recover the bus from certain conditions, which would
otherwise remain stuck forever.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Neal Gompa <neal@gompa.dev>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index 2f31f039bedfd7f78d6572fe925125b1a6d0724b..41db38d82fe62c73614b8fafe4cb73c7d1a24762 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -78,7 +78,7 @@ static inline int reg_read(struct pasemi_smbus *smbus, int reg)
 
 static void pasemi_reset(struct pasemi_smbus *smbus)
 {
-	u32 val = (CTL_MTR | CTL_MRR | (smbus->clk_div & CTL_CLK_M));
+	u32 val = (CTL_MTR | CTL_MRR | CTL_UJM | (smbus->clk_div & CTL_CLK_M));
 
 	if (smbus->hw_rev >= 6)
 		val |= CTL_EN;

-- 
2.34.1




^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 6/6] i2c: pasemi: Log bus reset causes
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
                   ` (4 preceding siblings ...)
  2025-04-15 15:36 ` [PATCH v2 5/6] i2c: pasemi: Enable the unjam machine Sven Peter via B4 Relay
@ 2025-04-15 15:37 ` Sven Peter via B4 Relay
  2025-04-17 13:10   ` Andi Shyti
  2025-04-16  1:38 ` [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Neal Gompa
  2025-04-17 13:16 ` Andi Shyti
  7 siblings, 1 reply; 17+ messages in thread
From: Sven Peter via B4 Relay @ 2025-04-15 15:37 UTC (permalink / raw)
  To: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Neal Gompa, Hector Martin
  Cc: linuxppc-dev, asahi, linux-arm-kernel, linux-i2c, linux-kernel,
	Sven Peter

From: Hector Martin <marcan@marcan.st>

This ensures we get all information we need to debug issues when users
forward us their logs.

Signed-off-by: Hector Martin <marcan@marcan.st>
Reviewed-by: Neal Gompa <neal@gompa.dev>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Signed-off-by: Sven Peter <sven@svenpeter.dev>
---
 drivers/i2c/busses/i2c-pasemi-core.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
index 41db38d82fe62c73614b8fafe4cb73c7d1a24762..e5e8a748638f02e48d6ffa65e49aff5b12f70e06 100644
--- a/drivers/i2c/busses/i2c-pasemi-core.c
+++ b/drivers/i2c/busses/i2c-pasemi-core.c
@@ -22,6 +22,7 @@
 /* Register offsets */
 #define REG_MTXFIFO	0x00
 #define REG_MRXFIFO	0x04
+#define REG_XFSTA	0x0c
 #define REG_SMSTA	0x14
 #define REG_IMASK	0x18
 #define REG_CTL		0x1c
@@ -89,7 +90,7 @@ static void pasemi_reset(struct pasemi_smbus *smbus)
 
 static int pasemi_smb_clear(struct pasemi_smbus *smbus)
 {
-	unsigned int status;
+	unsigned int status, xfstatus;
 	int ret;
 
 	/* First wait for the bus to go idle */
@@ -98,7 +99,9 @@ static int pasemi_smb_clear(struct pasemi_smbus *smbus)
 				 USEC_PER_MSEC, USEC_PER_MSEC * TRANSFER_TIMEOUT_MS);
 
 	if (ret < 0) {
-		dev_err(smbus->dev, "Bus is still stuck (status 0x%08x)\n", status);
+		xfstatus = reg_read(smbus, REG_XFSTA);
+		dev_err(smbus->dev, "Bus is still stuck (status 0x%08x xfstatus 0x%08x)\n",
+			 status, xfstatus);
 		return -EIO;
 	}
 

-- 
2.34.1




^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include
  2025-04-15 15:36 ` [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include Sven Peter via B4 Relay
@ 2025-04-15 17:10   ` Alyssa Rosenzweig
  0 siblings, 0 replies; 17+ messages in thread
From: Alyssa Rosenzweig @ 2025-04-15 17:10 UTC (permalink / raw)
  To: sven
  Cc: Janne Grunau, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Naveen N Rao, Andi Shyti,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel, Andy Shevchenko

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>

Le Tue , Apr 15, 2025 at 03:36:55PM +0000, Sven Peter via B4 Relay a écrit :
> From: Sven Peter <sven@svenpeter.dev>
> 
> When changing the #defines to use BIT and GENMASK the bitfield.h include
> was added instead of the correct bits.h include.
> 
> Reported-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Closes: https://lore.kernel.org/asahi/Z965tVhC5jxy1kqZ@surfacebook.localdomain/
> Fixes: 8b4da3ef9206 ("i2c: pasemi: Add registers bits and switch to BIT()")
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
>  drivers/i2c/busses/i2c-pasemi-core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
> index bd128ab2e2ebb64929f2f6a3525835a880c3114d..71cc8cfc7c5cbf3924269f6217712d42008c03ff 100644
> --- a/drivers/i2c/busses/i2c-pasemi-core.c
> +++ b/drivers/i2c/busses/i2c-pasemi-core.c
> @@ -5,7 +5,7 @@
>   * SMBus host driver for PA Semi PWRficient
>   */
>  
> -#include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
>  #include <linux/kernel.h>
> 
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 2/6] i2c: pasemi: Sort includes alphabetically
  2025-04-15 15:36 ` [PATCH v2 2/6] i2c: pasemi: Sort includes alphabetically Sven Peter via B4 Relay
@ 2025-04-15 17:11   ` Alyssa Rosenzweig
  0 siblings, 0 replies; 17+ messages in thread
From: Alyssa Rosenzweig @ 2025-04-15 17:11 UTC (permalink / raw)
  To: sven
  Cc: Janne Grunau, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Naveen N Rao, Andi Shyti,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>

Le Tue , Apr 15, 2025 at 03:36:56PM +0000, Sven Peter via B4 Relay a écrit :
> From: Sven Peter <sven@svenpeter.dev>
> 
> No functional changes.
> 
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
>  drivers/i2c/busses/i2c-pasemi-core.c | 10 +++++-----
>  drivers/i2c/busses/i2c-pasemi-pci.c  | 10 +++++-----
>  2 files changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
> index 71cc8cfc7c5cbf3924269f6217712d42008c03ff..df1b0087dcacb0a3b94196368137d5e20b0e6d7e 100644
> --- a/drivers/i2c/busses/i2c-pasemi-core.c
> +++ b/drivers/i2c/busses/i2c-pasemi-core.c
> @@ -6,15 +6,15 @@
>   */
>  
>  #include <linux/bits.h>
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> -#include <linux/kernel.h>
> -#include <linux/stddef.h>
>  #include <linux/sched.h>
> -#include <linux/i2c.h>
> -#include <linux/delay.h>
>  #include <linux/slab.h>
> -#include <linux/io.h>
> +#include <linux/stddef.h>
>  
>  #include "i2c-pasemi-core.h"
>  
> diff --git a/drivers/i2c/busses/i2c-pasemi-pci.c b/drivers/i2c/busses/i2c-pasemi-pci.c
> index 77f90c7436eda2df16afd7f1cac79355fb005bfd..b9ccb54ec77e22bb1b77848c858e2e0cc51db7e3 100644
> --- a/drivers/i2c/busses/i2c-pasemi-pci.c
> +++ b/drivers/i2c/busses/i2c-pasemi-pci.c
> @@ -5,15 +5,15 @@
>   * SMBus host driver for PA Semi PWRficient
>   */
>  
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> -#include <linux/kernel.h>
> -#include <linux/stddef.h>
>  #include <linux/sched.h>
> -#include <linux/i2c.h>
> -#include <linux/delay.h>
>  #include <linux/slab.h>
> -#include <linux/io.h>
> +#include <linux/stddef.h>
>  
>  #include "i2c-pasemi-core.h"
>  
> 
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/6] i2c: pasemi: Improve timeout handling
  2025-04-15 15:36 ` [PATCH v2 3/6] i2c: pasemi: Improve timeout handling Sven Peter via B4 Relay
@ 2025-04-15 17:11   ` Alyssa Rosenzweig
  2025-04-17 12:57   ` Andi Shyti
  1 sibling, 0 replies; 17+ messages in thread
From: Alyssa Rosenzweig @ 2025-04-15 17:11 UTC (permalink / raw)
  To: sven
  Cc: Janne Grunau, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Naveen N Rao, Andi Shyti,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>

Le Tue , Apr 15, 2025 at 03:36:57PM +0000, Sven Peter via B4 Relay a écrit :
> From: Sven Peter <sven@svenpeter.dev>
> 
> Add proper timeout handling for the interrupt path.
> Previously, this was only correctly done for the polling path.
> Note that we drop reg_write(smbus, REG_SMSTA, status) here which
> will be done anyway whenever the next transaction starts via
> pasemi_smb_clear.
> 
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
>  drivers/i2c/busses/i2c-pasemi-core.c | 24 +++++++++++++++++-------
>  1 file changed, 17 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
> index df1b0087dcacb0a3b94196368137d5e20b0e6d7e..9b611dbdfef23e78a4ea75ac0311938d52b6ba96 100644
> --- a/drivers/i2c/busses/i2c-pasemi-core.c
> +++ b/drivers/i2c/busses/i2c-pasemi-core.c
> @@ -91,32 +91,42 @@ static void pasemi_smb_clear(struct pasemi_smbus *smbus)
>  static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
>  {
>  	int timeout = 100;
> +	int ret;
>  	unsigned int status;
>  
>  	if (smbus->use_irq) {
>  		reinit_completion(&smbus->irq_completion);
>  		reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
> -		wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
> +		ret = wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
>  		reg_write(smbus, REG_IMASK, 0);
>  		status = reg_read(smbus, REG_SMSTA);
> +
> +		if (ret < 0) {
> +			dev_err(smbus->dev,
> +				"Completion wait failed with %d, status 0x%08x\n",
> +				ret, status);
> +			return ret;
> +		} else if (ret == 0) {
> +			dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
> +			return -ETIME;
> +		}
>  	} else {
>  		status = reg_read(smbus, REG_SMSTA);
>  		while (!(status & SMSTA_XEN) && timeout--) {
>  			msleep(1);
>  			status = reg_read(smbus, REG_SMSTA);
>  		}
> +
> +		if (timeout < 0) {
> +			dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
> +			return -ETIME;
> +		}
>  	}
>  
>  	/* Got NACK? */
>  	if (status & SMSTA_MTN)
>  		return -ENXIO;
>  
> -	if (timeout < 0) {
> -		dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
> -		reg_write(smbus, REG_SMSTA, status);
> -		return -ETIME;
> -	}
> -
>  	/* Clear XEN */
>  	reg_write(smbus, REG_SMSTA, SMSTA_XEN);
>  
> 
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 4/6] i2c: pasemi: Improve error recovery
  2025-04-15 15:36 ` [PATCH v2 4/6] i2c: pasemi: Improve error recovery Sven Peter via B4 Relay
@ 2025-04-15 17:12   ` Alyssa Rosenzweig
  2025-04-17 13:07   ` Andi Shyti
  1 sibling, 0 replies; 17+ messages in thread
From: Alyssa Rosenzweig @ 2025-04-15 17:12 UTC (permalink / raw)
  To: sven
  Cc: Janne Grunau, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Naveen N Rao, Andi Shyti,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>

Le Tue , Apr 15, 2025 at 03:36:58PM +0000, Sven Peter via B4 Relay a écrit :
> From: Hector Martin <marcan@marcan.st>
> 
> The hardware (supposedly) has a 25ms timeout for clock stretching
> and the driver uses 100ms which should be plenty. The error
> reocvery itself is however lacking.
> 
> Add handling for all the missing error condition, and better recovery in
> pasemi_smb_clear(). Also move the timeout to a #define since it's used
> in multiple places now.
> 
> Signed-off-by: Hector Martin <marcan@marcan.st>
> [sven: adjusted commit message after splitting the commit into two]
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
>  drivers/i2c/busses/i2c-pasemi-core.c | 75 +++++++++++++++++++++++++++++++-----
>  1 file changed, 65 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-pasemi-core.c b/drivers/i2c/busses/i2c-pasemi-core.c
> index 9b611dbdfef23e78a4ea75ac0311938d52b6ba96..2f31f039bedfd7f78d6572fe925125b1a6d0724b 100644
> --- a/drivers/i2c/busses/i2c-pasemi-core.c
> +++ b/drivers/i2c/busses/i2c-pasemi-core.c
> @@ -9,6 +9,7 @@
>  #include <linux/delay.h>
>  #include <linux/i2c.h>
>  #include <linux/io.h>
> +#include <linux/iopoll.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> @@ -52,6 +53,12 @@
>  #define CTL_UJM		BIT(8)
>  #define CTL_CLK_M	GENMASK(7, 0)
>  
> +/*
> + * The hardware (supposedly) has a 25ms timeout for clock stretching, thus
> + * use 100ms here which should be plenty.
> + */
> +#define TRANSFER_TIMEOUT_MS	100
> +
>  static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
>  {
>  	dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val);
> @@ -80,24 +87,44 @@ static void pasemi_reset(struct pasemi_smbus *smbus)
>  	reinit_completion(&smbus->irq_completion);
>  }
>  
> -static void pasemi_smb_clear(struct pasemi_smbus *smbus)
> +static int pasemi_smb_clear(struct pasemi_smbus *smbus)
>  {
>  	unsigned int status;
> +	int ret;
>  
> -	status = reg_read(smbus, REG_SMSTA);
> +	/* First wait for the bus to go idle */
> +	ret = readx_poll_timeout(ioread32, smbus->ioaddr + REG_SMSTA,
> +				 status, !(status & (SMSTA_XIP | SMSTA_JAM)),
> +				 USEC_PER_MSEC, USEC_PER_MSEC * TRANSFER_TIMEOUT_MS);
> +
> +	if (ret < 0) {
> +		dev_err(smbus->dev, "Bus is still stuck (status 0x%08x)\n", status);
> +		return -EIO;
> +	}
> +
> +	/* If any badness happened or there is data in the FIFOs, reset the FIFOs */
> +	if ((status & (SMSTA_MRNE | SMSTA_JMD | SMSTA_MTO | SMSTA_TOM | SMSTA_MTN | SMSTA_MTA)) ||
> +	    !(status & SMSTA_MTE))
> +		pasemi_reset(smbus);
> +
> +	/* Clear the flags */
>  	reg_write(smbus, REG_SMSTA, status);
> +
> +	return 0;
>  }
>  
>  static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
>  {
> -	int timeout = 100;
> +	int timeout = TRANSFER_TIMEOUT_MS;
>  	int ret;
>  	unsigned int status;
>  
>  	if (smbus->use_irq) {
>  		reinit_completion(&smbus->irq_completion);
> -		reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
> -		ret = wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
> +		/* XEN should be set when a transaction terminates, whether due to error or not */
> +		reg_write(smbus, REG_IMASK, SMSTA_XEN);
> +		ret = wait_for_completion_timeout(&smbus->irq_completion,
> +						  msecs_to_jiffies(timeout));
>  		reg_write(smbus, REG_IMASK, 0);
>  		status = reg_read(smbus, REG_SMSTA);
>  
> @@ -123,9 +150,35 @@ static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
>  		}
>  	}
>  
> +	/* Controller timeout? */
> +	if (status & SMSTA_TOM) {
> +		dev_warn(smbus->dev, "Controller timeout, status 0x%08x\n", status);
> +		return -EIO;
> +	}
> +
> +	/* Peripheral timeout? */
> +	if (status & SMSTA_MTO) {
> +		dev_warn(smbus->dev, "Peripheral timeout, status 0x%08x\n", status);
> +		return -ETIME;
> +	}
> +
> +	/* Still stuck in a transaction? */
> +	if (status & SMSTA_XIP) {
> +		dev_warn(smbus->dev, "Bus stuck, status 0x%08x\n", status);
> +		return -EIO;
> +	}
> +
> +	/* Arbitration loss? */
> +	if (status & SMSTA_MTA) {
> +		dev_warn(smbus->dev, "Arbitration loss, status 0x%08x\n", status);
> +		return -EBUSY;
> +	}
> +
>  	/* Got NACK? */
> -	if (status & SMSTA_MTN)
> +	if (status & SMSTA_MTN) {
> +		dev_warn(smbus->dev, "NACK, status 0x%08x\n", status);
>  		return -ENXIO;
> +	}
>  
>  	/* Clear XEN */
>  	reg_write(smbus, REG_SMSTA, SMSTA_XEN);
> @@ -187,9 +240,9 @@ static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
>  	struct pasemi_smbus *smbus = adapter->algo_data;
>  	int ret, i;
>  
> -	pasemi_smb_clear(smbus);
> -
> -	ret = 0;
> +	ret = pasemi_smb_clear(smbus);
> +	if (ret)
> +		return ret;
>  
>  	for (i = 0; i < num && !ret; i++)
>  		ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
> @@ -210,7 +263,9 @@ static int pasemi_smb_xfer(struct i2c_adapter *adapter,
>  	addr <<= 1;
>  	read_flag = read_write == I2C_SMBUS_READ;
>  
> -	pasemi_smb_clear(smbus);
> +	err = pasemi_smb_clear(smbus);
> +	if (err)
> +		return err;
>  
>  	switch (size) {
>  	case I2C_SMBUS_QUICK:
> 
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
                   ` (5 preceding siblings ...)
  2025-04-15 15:37 ` [PATCH v2 6/6] i2c: pasemi: Log bus reset causes Sven Peter via B4 Relay
@ 2025-04-16  1:38 ` Neal Gompa
  2025-04-17 13:16 ` Andi Shyti
  7 siblings, 0 replies; 17+ messages in thread
From: Neal Gompa @ 2025-04-16  1:38 UTC (permalink / raw)
  To: Sven Peter
  Cc: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Andi Shyti, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel, Andy Shevchenko

On Tue, Apr 15, 2025 at 11:37 AM Sven Peter via B4 Relay
<devnull+sven.svenpeter.dev@kernel.org> wrote:
>
> Hi,
>
> This series adds a few fixes/improvements to the error recovery for
> Apple/PASemi i2c controllers.
> The patches have been in our downstream tree and were originally used
> to debug a rare glitch caused by clock strechting but are useful in
> general. We haven't seen the controller misbehave since adding these.
>
> Best,
>
> Sven
>
> Signed-off-by: Sven Peter <sven@svenpeter.dev>
> ---
> Changes in v2:
> - Added commit to use the correct include (bits.h instead of bitfield.h)
> - Added commit to sort includes
> - Moved timeout explanations to code instead of just the commit log
> - Made timeout recovery also work correctly in the interrupt case when
>   waiting for the condition failed
> - Used readx_poll_timeout instead of open-coded alternative
> - Link to v1: https://lore.kernel.org/r/20250222-pasemi-fixes-v1-0-d7ea33d50c5e@svenpeter.dev
>
> ---
> Hector Martin (3):
>       i2c: pasemi: Improve error recovery
>       i2c: pasemi: Enable the unjam machine
>       i2c: pasemi: Log bus reset causes
>
> Sven Peter (3):
>       i2c: pasemi: Use correct bits.h include
>       i2c: pasemi: Sort includes alphabetically
>       i2c: pasemi: Improve timeout handling
>
>  drivers/i2c/busses/i2c-pasemi-core.c | 114 ++++++++++++++++++++++++++++-------
>  drivers/i2c/busses/i2c-pasemi-pci.c  |  10 +--
>  2 files changed, 96 insertions(+), 28 deletions(-)
> ---
> base-commit: 0af2f6be1b4281385b618cb86ad946eded089ac8
> change-id: 20250220-pasemi-fixes-916cb77404ba
>

The series looks good to me, especially the new patches.

Reviewed-by: Neal Gompa <neal@gompa.dev>


-- 
真実はいつも一つ!/ Always, there's only one truth!


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 3/6] i2c: pasemi: Improve timeout handling
  2025-04-15 15:36 ` [PATCH v2 3/6] i2c: pasemi: Improve timeout handling Sven Peter via B4 Relay
  2025-04-15 17:11   ` Alyssa Rosenzweig
@ 2025-04-17 12:57   ` Andi Shyti
  1 sibling, 0 replies; 17+ messages in thread
From: Andi Shyti @ 2025-04-17 12:57 UTC (permalink / raw)
  To: Sven Peter
  Cc: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Hi Sven,

>  static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
>  {
>  	int timeout = 100;
> +	int ret;

can you please declare this "ret" inside the if() statement
below?

>  	unsigned int status;
>  
>  	if (smbus->use_irq) {
>  		reinit_completion(&smbus->irq_completion);
>  		reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
> -		wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
> +		ret = wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
>  		reg_write(smbus, REG_IMASK, 0);
>  		status = reg_read(smbus, REG_SMSTA);
> +
> +		if (ret < 0) {
> +			dev_err(smbus->dev,
> +				"Completion wait failed with %d, status 0x%08x\n",
> +				ret, status);
> +			return ret;
> +		} else if (ret == 0) {
> +			dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
> +			return -ETIME;
> +		}
>  	} else {
>  		status = reg_read(smbus, REG_SMSTA);
>  		while (!(status & SMSTA_XEN) && timeout--) {
>  			msleep(1);
>  			status = reg_read(smbus, REG_SMSTA);
>  		}
> +
> +		if (timeout < 0) {
> +			dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);

this is an error and it's treated as an error, can we please
print dev_err()?

Andi

> +			return -ETIME;
> +		}
>  	}


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 4/6] i2c: pasemi: Improve error recovery
  2025-04-15 15:36 ` [PATCH v2 4/6] i2c: pasemi: Improve error recovery Sven Peter via B4 Relay
  2025-04-15 17:12   ` Alyssa Rosenzweig
@ 2025-04-17 13:07   ` Andi Shyti
  2025-04-27 11:29     ` Sven Peter
  1 sibling, 1 reply; 17+ messages in thread
From: Andi Shyti @ 2025-04-17 13:07 UTC (permalink / raw)
  To: Sven Peter
  Cc: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Hi Sven, Hector,

...

> +/*
> + * The hardware (supposedly) has a 25ms timeout for clock stretching, thus
> + * use 100ms here which should be plenty.
> + */
> +#define TRANSFER_TIMEOUT_MS	100

Please use the PASEMI prefix here. TRANSFER_TIMEOUT_MS it's not a
naming belonging to this driver.

100ms looks a bit too much to me, but if you say it works, then
it works.

> +

...

>  	unsigned int status;
>  
>  	if (smbus->use_irq) {
>  		reinit_completion(&smbus->irq_completion);
> -		reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
> -		ret = wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
> +		/* XEN should be set when a transaction terminates, whether due to error or not */
> +		reg_write(smbus, REG_IMASK, SMSTA_XEN);
> +		ret = wait_for_completion_timeout(&smbus->irq_completion,
> +						  msecs_to_jiffies(timeout));
>  		reg_write(smbus, REG_IMASK, 0);
>  		status = reg_read(smbus, REG_SMSTA);
>  
> @@ -123,9 +150,35 @@ static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
>  		}
>  	}
>  
> +	/* Controller timeout? */
> +	if (status & SMSTA_TOM) {
> +		dev_warn(smbus->dev, "Controller timeout, status 0x%08x\n", status);
> +		return -EIO;

as before, these warnings are treated as errors. Can we just
print error?

The rest looks good.

Andi

> +	}
> +
> +	/* Peripheral timeout? */
> +	if (status & SMSTA_MTO) {
> +		dev_warn(smbus->dev, "Peripheral timeout, status 0x%08x\n", status);
> +		return -ETIME;
> +	}

...


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 6/6] i2c: pasemi: Log bus reset causes
  2025-04-15 15:37 ` [PATCH v2 6/6] i2c: pasemi: Log bus reset causes Sven Peter via B4 Relay
@ 2025-04-17 13:10   ` Andi Shyti
  0 siblings, 0 replies; 17+ messages in thread
From: Andi Shyti @ 2025-04-17 13:10 UTC (permalink / raw)
  To: Sven Peter
  Cc: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Hi Sven,

...

>  static int pasemi_smb_clear(struct pasemi_smbus *smbus)
>  {
> -	unsigned int status;
> +	unsigned int status, xfstatus;

Let's declare the variables in the innermost scope where they are
used.

Andi

>  	int ret;
>  
>  	/* First wait for the bus to go idle */
> @@ -98,7 +99,9 @@ static int pasemi_smb_clear(struct pasemi_smbus *smbus)
>  				 USEC_PER_MSEC, USEC_PER_MSEC * TRANSFER_TIMEOUT_MS);
>  
>  	if (ret < 0) {
> -		dev_err(smbus->dev, "Bus is still stuck (status 0x%08x)\n", status);
> +		xfstatus = reg_read(smbus, REG_XFSTA);
> +		dev_err(smbus->dev, "Bus is still stuck (status 0x%08x xfstatus 0x%08x)\n",
> +			 status, xfstatus);
>  		return -EIO;
>  	}
>  
> 
> -- 
> 2.34.1
> 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes
  2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
                   ` (6 preceding siblings ...)
  2025-04-16  1:38 ` [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Neal Gompa
@ 2025-04-17 13:16 ` Andi Shyti
  7 siblings, 0 replies; 17+ messages in thread
From: Andi Shyti @ 2025-04-17 13:16 UTC (permalink / raw)
  To: Sven Peter
  Cc: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel, Andy Shevchenko

Hi Sven,

> Hector Martin (3):
>       i2c: pasemi: Improve error recovery
>       i2c: pasemi: Enable the unjam machine
>       i2c: pasemi: Log bus reset causes
> 
> Sven Peter (3):
>       i2c: pasemi: Use correct bits.h include
>       i2c: pasemi: Sort includes alphabetically

I applied in i2c/i2c-host the two patches above, so that you can
start from patch 3 as there were a few little notes.

I didn't see necessary the Fixes tag in the bits.h patch so that
I removed it.

Thanks,
Andi


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 4/6] i2c: pasemi: Improve error recovery
  2025-04-17 13:07   ` Andi Shyti
@ 2025-04-27 11:29     ` Sven Peter
  0 siblings, 0 replies; 17+ messages in thread
From: Sven Peter @ 2025-04-27 11:29 UTC (permalink / raw)
  To: Andi Shyti
  Cc: Janne Grunau, Alyssa Rosenzweig, Madhavan Srinivasan,
	Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Neal Gompa, Hector Martin, linuxppc-dev, asahi, linux-arm-kernel,
	linux-i2c, linux-kernel

Hi,


On Thu, Apr 17, 2025, at 15:07, Andi Shyti wrote:
> Hi Sven, Hector,
>
> ...
>
>> +/*
>> + * The hardware (supposedly) has a 25ms timeout for clock stretching, thus
>> + * use 100ms here which should be plenty.
>> + */
>> +#define TRANSFER_TIMEOUT_MS	100
>
> Please use the PASEMI prefix here. TRANSFER_TIMEOUT_MS it's not a
> naming belonging to this driver.
>
> 100ms looks a bit too much to me, but if you say it works, then
> it works.
>

The problem here is that we only have very outdated documentation for this
hardware and no real idea what changed since Apple bought PASemi and continued
using their i2c controller.
We know that 10ms (which used to be the original timeout iirc) is not nearly
enough and we also know that we need at least 25ms for clock strechting
(assuming nothing changed in the past 10+ years).
We just bumped it to 100ms to be safe after we very rarely got error
reports which we tracked down to timeouts and haven't gotten any reports
since.


I've addressed all your other comments for v3 which I'll send out in a few minutes.


Best,


Sven


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2025-04-27 11:31 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-15 15:36 [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Sven Peter via B4 Relay
2025-04-15 15:36 ` [PATCH v2 1/6] i2c: pasemi: Use correct bits.h include Sven Peter via B4 Relay
2025-04-15 17:10   ` Alyssa Rosenzweig
2025-04-15 15:36 ` [PATCH v2 2/6] i2c: pasemi: Sort includes alphabetically Sven Peter via B4 Relay
2025-04-15 17:11   ` Alyssa Rosenzweig
2025-04-15 15:36 ` [PATCH v2 3/6] i2c: pasemi: Improve timeout handling Sven Peter via B4 Relay
2025-04-15 17:11   ` Alyssa Rosenzweig
2025-04-17 12:57   ` Andi Shyti
2025-04-15 15:36 ` [PATCH v2 4/6] i2c: pasemi: Improve error recovery Sven Peter via B4 Relay
2025-04-15 17:12   ` Alyssa Rosenzweig
2025-04-17 13:07   ` Andi Shyti
2025-04-27 11:29     ` Sven Peter
2025-04-15 15:36 ` [PATCH v2 5/6] i2c: pasemi: Enable the unjam machine Sven Peter via B4 Relay
2025-04-15 15:37 ` [PATCH v2 6/6] i2c: pasemi: Log bus reset causes Sven Peter via B4 Relay
2025-04-17 13:10   ` Andi Shyti
2025-04-16  1:38 ` [PATCH v2 0/6] Apple/PASemi i2c error recovery fixes Neal Gompa
2025-04-17 13:16 ` Andi Shyti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).