linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mathieu Poirier <mathieu.poirier@linaro.org>
To: stable@vger.kernel.org
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pm@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linux-omap@vger.kernel.org, linux-i2c@vger.kernel.org,
	linux-pci@vger.kernel.org, linux-mtd@lists.infradead.org
Subject: [BACKPORT 4.14.y 17/18] i2c: omap: Trigger bus recovery in lockup case
Date: Thu,  5 Sep 2019 10:17:58 -0600	[thread overview]
Message-ID: <20190905161759.28036-18-mathieu.poirier@linaro.org> (raw)
In-Reply-To: <20190905161759.28036-1-mathieu.poirier@linaro.org>

From: Claudio Foellmi <claudio.foellmi@ergon.ch>

commit 93367bfca98f36cece57c01dbce6ea1b4ac58245 upstream

A very conservative check for bus activity (to prevent interference
in multimaster setups) prevented the bus recovery methods from being
triggered in the case that SDA or SCL was stuck low.
This defeats the purpose of the recovery mechanism, which was introduced
for exactly this situation (a slave device keeping SDA pulled down).

Also added a check to make sure SDA is low before attempting recovery.
If SDA is not stuck low, recovery will not help, so we can skip it.

Note that bus lockups can persist across reboots. The only other options
are to reset or power cycle the offending slave device, and many i2c
slaves do not even have a reset pin.

If we see that one of the lines is low for the entire timeout duration,
we can actually be sure that there is no other master driving the bus.
It is therefore save for us to attempt a bus recovery.

Signed-off-by: Claudio Foellmi <claudio.foellmi@ergon.ch>
Tested-by: Vignesh R <vigneshr@ti.com>
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
[wsa: fixed one return code to -EBUSY]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/i2c/busses/i2c-omap.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 12ba183693d6..a03564f41ad0 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -486,6 +486,22 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
 	return 0;
 }
 
+/*
+ * Try bus recovery, but only if SDA is actually low.
+ */
+static int omap_i2c_recover_bus(struct omap_i2c_dev *omap)
+{
+	u16 systest;
+
+	systest = omap_i2c_read_reg(omap, OMAP_I2C_SYSTEST_REG);
+	if ((systest & OMAP_I2C_SYSTEST_SCL_I_FUNC) &&
+	    (systest & OMAP_I2C_SYSTEST_SDA_I_FUNC))
+		return 0; /* bus seems to already be fine */
+	if (!(systest & OMAP_I2C_SYSTEST_SCL_I_FUNC))
+		return -EBUSY; /* recovery would not fix SCL */
+	return i2c_recover_bus(&omap->adapter);
+}
+
 /*
  * Waiting on Bus Busy
  */
@@ -496,7 +512,7 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *omap)
 	timeout = jiffies + OMAP_I2C_TIMEOUT;
 	while (omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG) & OMAP_I2C_STAT_BB) {
 		if (time_after(jiffies, timeout))
-			return i2c_recover_bus(&omap->adapter);
+			return omap_i2c_recover_bus(omap);
 		msleep(1);
 	}
 
@@ -577,8 +593,13 @@ static int omap_i2c_wait_for_bb_valid(struct omap_i2c_dev *omap)
 		}
 
 		if (time_after(jiffies, timeout)) {
+			/*
+			 * SDA or SCL were low for the entire timeout without
+			 * any activity detected. Most likely, a slave is
+			 * locking up the bus with no master driving the clock.
+			 */
 			dev_warn(omap->dev, "timeout waiting for bus ready\n");
-			return -ETIMEDOUT;
+			return omap_i2c_recover_bus(omap);
 		}
 
 		msleep(1);
-- 
2.17.1


  parent reply	other threads:[~2019-09-05 16:18 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-05 16:17 [BACKPORT 4.14.y 00/18] Backport candidate from TI 4.14 product kernel Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 01/18] PCI: designware-ep: Fix find_first_zero_bit() usage Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 02/18] PCI: dra7xx: Fix legacy INTD IRQ handling Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 03/18] drm/omap: panel-dsi-cm: fix driver Mathieu Poirier
2019-09-10 14:34   ` Greg KH
2019-09-11 11:48     ` Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 04/18] usb: dwc3: Allow disabling of metastability workaround Mathieu Poirier
2019-09-10 14:36   ` Greg KH
2019-09-11 14:01     ` Mathieu Poirier
2019-11-11  9:16       ` Greg KH
2019-09-05 16:17 ` [BACKPORT 4.14.y 05/18] mfd: palmas: Assign the right powerhold mask for tps65917 Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 06/18] ASoC: tlv320aic31xx: Handle inverted BCLK in non-DSP modes Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 07/18] mtd: spi-nor: enable 4B opcodes for mx66l51235l Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 08/18] mtd: spi-nor: cadence-quadspi: add a delay in write sequence Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 09/18] misc: pci_endpoint_test: Prevent some integer overflows Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 10/18] PCI: dra7xx: Add shutdown handler to cleanly turn off clocks Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 11/18] misc: pci_endpoint_test: Fix BUG_ON error during pci_disable_msi() Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 12/18] mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 13/18] ASoC: tlv320dac31xx: mark expected switch fall-through Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 14/18] ASoC: davinci-mcasp: Handle return value of devm_kasprintf Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 15/18] ASoC: davinci: Kill BUG_ON() usage Mathieu Poirier
2019-09-05 16:17 ` [BACKPORT 4.14.y 16/18] ASoC: davinci-mcasp: Fix an error handling path in 'davinci_mcasp_probe()' Mathieu Poirier
2019-09-05 16:17 ` Mathieu Poirier [this message]
2019-09-05 16:17 ` [BACKPORT 4.14.y 18/18] cpufreq: ti-cpufreq: add missing of_node_put() Mathieu Poirier
2019-09-05 16:24 ` [BACKPORT 4.14.y 00/18] Backport candidate from TI 4.14 product kernel Wolfram Sang

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=20190905161759.28036-18-mathieu.poirier@linaro.org \
    --to=mathieu.poirier@linaro.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).