3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shubhrajyoti Datta shubhrajyoti.datta@xilinx.com
commit ae7304c3ea28a3ba47a7a8312c76c654ef24967e upstream.
Disable interrupts while configuring the transfer and enable them back.
We have below as the programming sequence 1. start and slave address 2. byte count and stop
In some customer platform there was a lot of interrupts between 1 and 2 and after slave address (around 7 clock cyles) if 2 is not executed then the transaction is nacked.
To fix this case make the 2 writes atomic.
Signed-off-by: Shubhrajyoti Datta shubhrajyoti.datta@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com [wsa: added a newline for better readability] Signed-off-by: Wolfram Sang wsa@the-dreams.de Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/i2c/busses/i2c-xiic.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -500,6 +500,7 @@ static void xiic_start_recv(struct xiic_ { u8 rx_watermark; struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg; + unsigned long flags;
/* Clear and enable Rx full interrupt. */ xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK); @@ -515,6 +516,7 @@ static void xiic_start_recv(struct xiic_ rx_watermark = IIC_RX_FIFO_DEPTH; xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
+ local_irq_save(flags); if (!(msg->flags & I2C_M_NOSTART)) /* write the address */ xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, @@ -525,6 +527,8 @@ static void xiic_start_recv(struct xiic_
xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0)); + local_irq_restore(flags); + if (i2c->nmsgs == 1) /* very last, enable bus not busy as well */ xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);