summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorShubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>2019-02-05 16:42:53 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-03-23 14:35:13 +0100
commit4bd491fd4c496589d8d9adbba3eb6d6f294baefe (patch)
treed9405e42a5fcc1937702fbe19ca6149aebca86fa /drivers/i2c/busses
parente5f4a0bb7915d4d7f73320c57d37dde6fc16c64d (diff)
downloadlinux-stable-4bd491fd4c496589d8d9adbba3eb6d6f294baefe.tar.gz
linux-stable-4bd491fd4c496589d8d9adbba3eb6d6f294baefe.tar.bz2
linux-stable-4bd491fd4c496589d8d9adbba3eb6d6f294baefe.zip
i2c: cadence: Fix the hold bit setting
[ Upstream commit d358def706880defa4c9e87381c5bf086a97d5f9 ] In case the hold bit is not needed we are carrying the old values. Fix the same by resetting the bit when not needed. Fixes the sporadic i2c bus lockups on National Instruments Zynq-based devices. Fixes: df8eb5691c48 ("i2c: Add driver for Cadence I2C controller") Reported-by: Kyle Roeschley <kyle.roeschley@ni.com> Acked-by: Michal Simek <michal.simek@xilinx.com> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com> Tested-by: Kyle Roeschley <kyle.roeschley@ni.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-cadence.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index b13605718291..d917cefc5a19 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -382,8 +382,10 @@ static void cdns_i2c_mrecv(struct cdns_i2c *id)
* Check for the message size against FIFO depth and set the
* 'hold bus' bit if it is greater than FIFO depth.
*/
- if (id->recv_count > CDNS_I2C_FIFO_DEPTH)
+ if ((id->recv_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag)
ctrl_reg |= CDNS_I2C_CR_HOLD;
+ else
+ ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD;
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
@@ -440,8 +442,11 @@ static void cdns_i2c_msend(struct cdns_i2c *id)
* Check for the message size against FIFO depth and set the
* 'hold bus' bit if it is greater than FIFO depth.
*/
- if (id->send_count > CDNS_I2C_FIFO_DEPTH)
+ if ((id->send_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag)
ctrl_reg |= CDNS_I2C_CR_HOLD;
+ else
+ ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD;
+
cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET);
/* Clear the interrupts in interrupt status register. */