From 9374ed1dfe1f862f6dd7552b8164252fe5cc424f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 29 Aug 2020 22:38:09 +0200 Subject: i2c: rcar: improve bus busy detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I2C doesn't define a timeout for bus busy, so an arbitrary value like LOOP_TIMEOUT is not a good idea. Let's use the timeout value in struct adapter which is meant for such cases and is user-configurable (via IOCTL). To reduce the load, wait 10us instead of 1us which is good enough for the slow frequencies used by I2C. Finally, use the poll_timeout helper instead of open coding it. Signed-off-by: Wolfram Sang Reviewed-by: Niklas Söderlund Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-rcar.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/i2c/busses/i2c-rcar.c') diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 9e883474db8c..c5ba018d74a7 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -221,18 +222,18 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv) static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) { - int i; + int ret; + u32 val; - for (i = 0; i < LOOP_TIMEOUT; i++) { - /* make sure that bus is not busy */ - if (!(rcar_i2c_read(priv, ICMCR) & FSDA)) - return 0; - udelay(1); + ret = readl_poll_timeout(priv->io + ICMCR, val, !(val & FSDA), 10, + priv->adap.timeout); + if (ret) { + /* Waiting did not help, try to recover */ + priv->recovery_icmcr = MDBS | OBPC | FSDA | FSCL; + ret = i2c_recover_bus(&priv->adap); } - /* Waiting did not help, try to recover */ - priv->recovery_icmcr = MDBS | OBPC | FSDA | FSCL; - return i2c_recover_bus(&priv->adap); + return ret; } static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv) -- cgit v1.2.3