]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.157/i2c-xiic-make-the-start-and-the-byte-count-write-atomic.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.157 / i2c-xiic-make-the-start-and-the-byte-count-write-atomic.patch
CommitLineData
6de0c908
GKH
1From ae7304c3ea28a3ba47a7a8312c76c654ef24967e Mon Sep 17 00:00:00 2001
2From: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
3Date: Mon, 3 Sep 2018 15:11:11 +0530
4Subject: i2c: xiic: Make the start and the byte count write atomic
5
6From: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
7
8commit ae7304c3ea28a3ba47a7a8312c76c654ef24967e upstream.
9
10Disable interrupts while configuring the transfer and enable them back.
11
12We have below as the programming sequence
131. start and slave address
142. byte count and stop
15
16In some customer platform there was a lot of interrupts between 1 and 2
17and after slave address (around 7 clock cyles) if 2 is not executed
18then the transaction is nacked.
19
20To fix this case make the 2 writes atomic.
21
22Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
23Signed-off-by: Michal Simek <michal.simek@xilinx.com>
24[wsa: added a newline for better readability]
25Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
26Cc: stable@kernel.org
27Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29---
30 drivers/i2c/busses/i2c-xiic.c | 4 ++++
31 1 file changed, 4 insertions(+)
32
33--- a/drivers/i2c/busses/i2c-xiic.c
34+++ b/drivers/i2c/busses/i2c-xiic.c
35@@ -533,6 +533,7 @@ static void xiic_start_recv(struct xiic_
36 {
37 u8 rx_watermark;
38 struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
39+ unsigned long flags;
40
41 /* Clear and enable Rx full interrupt. */
42 xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
43@@ -548,6 +549,7 @@ static void xiic_start_recv(struct xiic_
44 rx_watermark = IIC_RX_FIFO_DEPTH;
45 xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
46
47+ local_irq_save(flags);
48 if (!(msg->flags & I2C_M_NOSTART))
49 /* write the address */
50 xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
51@@ -558,6 +560,8 @@ static void xiic_start_recv(struct xiic_
52
53 xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
54 msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
55+ local_irq_restore(flags);
56+
57 if (i2c->nmsgs == 1)
58 /* very last, enable bus not busy as well */
59 xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);