| From 9ea359f7314132cbcb5a502d2d8ef095be1f45e4 Mon Sep 17 00:00:00 2001 |
| From: Grygorii Strashko <grygorii.strashko@ti.com> |
| Date: Mon, 1 Dec 2014 17:34:04 +0200 |
| Subject: i2c: davinci: generate STP always when NACK is received |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Grygorii Strashko <grygorii.strashko@ti.com> |
| |
| commit 9ea359f7314132cbcb5a502d2d8ef095be1f45e4 upstream. |
| |
| According to I2C specification the NACK should be handled as follows: |
| "When SDA remains HIGH during this ninth clock pulse, this is defined as the Not |
| Acknowledge signal. The master can then generate either a STOP condition to |
| abort the transfer, or a repeated START condition to start a new transfer." |
| [I2C spec Rev. 6, 3.1.6: http://www.nxp.com/documents/user_manual/UM10204.pdf] |
| |
| Currently the Davinci i2c driver interrupts the transfer on receipt of a |
| NACK but fails to send a STOP in some situations and so makes the bus |
| stuck until next I2C IP reset (idle/enable). |
| |
| For example, the issue will happen during SMBus read transfer which |
| consists from two i2c messages write command/address and read data: |
| |
| S Slave Address Wr A Command Code A Sr Slave Address Rd A D1..Dn A P |
| <--- write -----------------------> <--- read ---------------------> |
| |
| The I2C client device will send NACK if it can't recognize "Command Code" |
| and it's expected from I2C master to generate STP in this case. |
| But now, Davinci i2C driver will just exit with -EREMOTEIO and STP will |
| not be generated. |
| |
| Hence, fix it by generating Stop condition (STP) always when NACK is received. |
| |
| This patch fixes Davinci I2C in the same way it was done for OMAP I2C |
| commit cda2109a26eb ("i2c: omap: query STP always when NACK is received"). |
| |
| Reviewed-by: Uwe Kleine-Kรถnig <u.kleine-koenig@pengutronix.de> |
| Reported-by: Hein Tibosch <hein_tibosch@yahoo.es> |
| Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> |
| Signed-off-by: Wolfram Sang <wsa@the-dreams.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/i2c/busses/i2c-davinci.c | 8 +++----- |
| 1 file changed, 3 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/i2c/busses/i2c-davinci.c |
| +++ b/drivers/i2c/busses/i2c-davinci.c |
| @@ -414,11 +414,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter |
| if (dev->cmd_err & DAVINCI_I2C_STR_NACK) { |
| if (msg->flags & I2C_M_IGNORE_NAK) |
| return msg->len; |
| - if (stop) { |
| - w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); |
| - w |= DAVINCI_I2C_MDR_STP; |
| - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); |
| - } |
| + w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); |
| + w |= DAVINCI_I2C_MDR_STP; |
| + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); |
| return -EREMOTEIO; |
| } |
| return -EIO; |