From a244839048b720a44736071f332ae5b0d6179ec3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Oct 2014 12:35:37 -0700 Subject: [PATCH] 3.16-stable patches added patches: i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch i2c-ismt-use-correct-length-when-copy-buffer.patch i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch i2c-rcar-fix-mnr-interrupt-handling.patch i2c-rcar-fix-rcar_irq_ack_-recv-send.patch i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch revert-i2c-rcar-remove-spinlock.patch --- ...checking-on-smbus-block-length-bytes.patch | 87 ++++++++++++++ ...-signal-handling-in-at91_do_twi_xfer.patch | 47 ++++++++ ...-use-correct-length-when-copy-buffer.patch | 42 +++++++ ...robe-when-clock-frequency-is-missing.patch | 46 ++++++++ .../i2c-rcar-fix-mnr-interrupt-handling.patch | 63 ++++++++++ ...i2c-rcar-fix-rcar_irq_ack_-recv-send.patch | 34 ++++++ ...ransfer-fails-in-master-receive-mode.patch | 38 ++++++ ...ivisor-calculation-for-scl-frequency.patch | 49 ++++++++ .../revert-i2c-rcar-remove-spinlock.patch | 110 ++++++++++++++++++ queue-3.16/series | 9 ++ 10 files changed, 525 insertions(+) create mode 100644 queue-3.16/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch create mode 100644 queue-3.16/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch create mode 100644 queue-3.16/i2c-ismt-use-correct-length-when-copy-buffer.patch create mode 100644 queue-3.16/i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch create mode 100644 queue-3.16/i2c-rcar-fix-mnr-interrupt-handling.patch create mode 100644 queue-3.16/i2c-rcar-fix-rcar_irq_ack_-recv-send.patch create mode 100644 queue-3.16/i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch create mode 100644 queue-3.16/i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch create mode 100644 queue-3.16/revert-i2c-rcar-remove-spinlock.patch diff --git a/queue-3.16/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch b/queue-3.16/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch new file mode 100644 index 00000000000..f2478412c28 --- /dev/null +++ b/queue-3.16/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch @@ -0,0 +1,87 @@ +From 75b81f339c6af43f6f4a1b3eabe0603321dade65 Mon Sep 17 00:00:00 2001 +From: Marek Roszko +Date: Wed, 20 Aug 2014 21:39:41 -0400 +Subject: i2c: at91: add bound checking on SMBus block length bytes + +From: Marek Roszko + +commit 75b81f339c6af43f6f4a1b3eabe0603321dade65 upstream. + +The driver was not bound checking the received length byte to ensure it was within the +the buffer size that is allocated for SMBus blocks. This resulted in buffer overflows +whenever an invalid length byte was received. +It also failed to ensure the length byte was not zero. If it received zero, it would end up +in an infinite loop as the at91_twi_read_next_byte function returned immediately without +allowing RHR to be read to clear the RXRDY interrupt. + +Tested agaisnt a SMBus compliant battery. + +Signed-off-by: Marek Roszko +Acked-by: Ludovic Desroches +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-at91.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +--- a/drivers/i2c/busses/i2c-at91.c ++++ b/drivers/i2c/busses/i2c-at91.c +@@ -101,6 +101,7 @@ struct at91_twi_dev { + unsigned twi_cwgr_reg; + struct at91_twi_pdata *pdata; + bool use_dma; ++ bool recv_len_abort; + struct at91_twi_dma dma; + }; + +@@ -267,12 +268,24 @@ static void at91_twi_read_next_byte(stru + *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff; + --dev->buf_len; + ++ /* return if aborting, we only needed to read RHR to clear RXRDY*/ ++ if (dev->recv_len_abort) ++ return; ++ + /* handle I2C_SMBUS_BLOCK_DATA */ + if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) { +- dev->msg->flags &= ~I2C_M_RECV_LEN; +- dev->buf_len += *dev->buf; +- dev->msg->len = dev->buf_len + 1; +- dev_dbg(dev->dev, "received block length %d\n", dev->buf_len); ++ /* ensure length byte is a valid value */ ++ if (*dev->buf <= I2C_SMBUS_BLOCK_MAX && *dev->buf > 0) { ++ dev->msg->flags &= ~I2C_M_RECV_LEN; ++ dev->buf_len += *dev->buf; ++ dev->msg->len = dev->buf_len + 1; ++ dev_dbg(dev->dev, "received block length %d\n", ++ dev->buf_len); ++ } else { ++ /* abort and send the stop by reading one more byte */ ++ dev->recv_len_abort = true; ++ dev->buf_len = 1; ++ } + } + + /* send stop if second but last byte has been read */ +@@ -444,6 +457,12 @@ static int at91_do_twi_transfer(struct a + ret = -EIO; + goto error; + } ++ if (dev->recv_len_abort) { ++ dev_err(dev->dev, "invalid smbus block length recvd\n"); ++ ret = -EPROTO; ++ goto error; ++ } ++ + dev_dbg(dev->dev, "transfer complete\n"); + + return 0; +@@ -500,6 +519,7 @@ static int at91_twi_xfer(struct i2c_adap + dev->buf_len = m_start->len; + dev->buf = m_start->buf; + dev->msg = m_start; ++ dev->recv_len_abort = false; + + ret = at91_do_twi_transfer(dev); + diff --git a/queue-3.16/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch b/queue-3.16/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch new file mode 100644 index 00000000000..0ccff5c8fe8 --- /dev/null +++ b/queue-3.16/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch @@ -0,0 +1,47 @@ +From 6721f28a26efd6368497abbdef5dcfc59608d899 Mon Sep 17 00:00:00 2001 +From: Simon Lindgren +Date: Tue, 26 Aug 2014 21:13:24 +0200 +Subject: i2c: at91: Fix a race condition during signal handling in at91_do_twi_xfer. + +From: Simon Lindgren + +commit 6721f28a26efd6368497abbdef5dcfc59608d899 upstream. + +There is a race condition in at91_do_twi_xfer when signals arrive. +If a signal is recieved while waiting for a transfer to complete +wait_for_completion_interruptible_timeout() will return -ERESTARTSYS. +This is not handled correctly resulting in interrupts still being +enabled and a transfer being in flight when we return. + +Symptoms include a range of oopses and bus lockups. Oopses can happen +when the transfer completes because the interrupt handler will corrupt +the stack. If a new transfer is started before the interrupt fires +the controller will start a new transfer in the middle of the old one, +resulting in confused slaves and a locked bus. + +To avoid this, use wait_for_completion_io_timeout instead so that we +don't have to deal with gracefully shutting down the transfer and +disabling the interrupts. + +Signed-off-by: Simon Lindgren +Acked-by: Ludovic Desroches +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-at91.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-at91.c ++++ b/drivers/i2c/busses/i2c-at91.c +@@ -434,8 +434,8 @@ static int at91_do_twi_transfer(struct a + } + } + +- ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, +- dev->adapter.timeout); ++ ret = wait_for_completion_io_timeout(&dev->cmd_complete, ++ dev->adapter.timeout); + if (ret == 0) { + dev_err(dev->dev, "controller timed out\n"); + at91_init_twi_bus(dev); diff --git a/queue-3.16/i2c-ismt-use-correct-length-when-copy-buffer.patch b/queue-3.16/i2c-ismt-use-correct-length-when-copy-buffer.patch new file mode 100644 index 00000000000..bd1950fdd72 --- /dev/null +++ b/queue-3.16/i2c-ismt-use-correct-length-when-copy-buffer.patch @@ -0,0 +1,42 @@ +From 979bbf7b7ae75cfc06e09d09eda38009a3bdc4a4 Mon Sep 17 00:00:00 2001 +From: Fan Du +Date: Tue, 16 Sep 2014 17:21:04 +0800 +Subject: i2c: ismt: use correct length when copy buffer + +From: Fan Du + +commit 979bbf7b7ae75cfc06e09d09eda38009a3bdc4a4 upstream. + +In block write mode, when encapsulating dma_buffer, first element is +'command', the rest is data buffer, so only copy actual data buffer +starting from block[1] with the size indicating by block[0]. + +Signed-off-by: Fan Du +Acked-by: Neil Horman +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-ismt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-ismt.c ++++ b/drivers/i2c/busses/i2c-ismt.c +@@ -497,7 +497,7 @@ static int ismt_access(struct i2c_adapte + desc->wr_len_cmd = dma_size; + desc->control |= ISMT_DESC_BLK; + priv->dma_buffer[0] = command; +- memcpy(&priv->dma_buffer[1], &data->block[1], dma_size); ++ memcpy(&priv->dma_buffer[1], &data->block[1], dma_size - 1); + } else { + /* Block Read */ + dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA: READ\n"); +@@ -525,7 +525,7 @@ static int ismt_access(struct i2c_adapte + desc->wr_len_cmd = dma_size; + desc->control |= ISMT_DESC_I2C; + priv->dma_buffer[0] = command; +- memcpy(&priv->dma_buffer[1], &data->block[1], dma_size); ++ memcpy(&priv->dma_buffer[1], &data->block[1], dma_size - 1); + } else { + /* i2c Block Read */ + dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: READ\n"); diff --git a/queue-3.16/i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch b/queue-3.16/i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch new file mode 100644 index 00000000000..a69fc60281d --- /dev/null +++ b/queue-3.16/i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch @@ -0,0 +1,46 @@ +From 0ce4bc1dbdd911ae1763e2d4ff36bd1b214a59f7 Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Mon, 1 Sep 2014 22:28:13 +0800 +Subject: i2c: mv64xxx: continue probe when clock-frequency is missing + +From: Chen-Yu Tsai + +commit 0ce4bc1dbdd911ae1763e2d4ff36bd1b214a59f7 upstream. + +The "clock-frequency" DT property is listed as optional, However, +the current code stores the return value of of_property_read_u32 in +the return code of mv64xxx_of_config, but then forgets to clear it +after setting the default value of "clock-frequency". It is then +passed out to the main probe function, resulting in a probe failure +when "clock-frequency" is missing. + +This patch checks and then throws away the return value of +of_property_read_u32, instead of storing it and having to clear it +afterwards. + +This issue was discovered after the property was removed from all +sunxi DTs. + +Fixes: 4c730a06c19bb ("i2c: mv64xxx: Set bus frequency to 100kHz if clock-frequency is not provided") +Signed-off-by: Chen-Yu Tsai +Acked-by: Andrew Lunn +Acked-by: Maxime Ripard +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-mv64xxx.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-mv64xxx.c ++++ b/drivers/i2c/busses/i2c-mv64xxx.c +@@ -746,8 +746,7 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat + } + tclk = clk_get_rate(drv_data->clk); + +- rc = of_property_read_u32(np, "clock-frequency", &bus_freq); +- if (rc) ++ if (of_property_read_u32(np, "clock-frequency", &bus_freq)) + bus_freq = 100000; /* 100kHz by default */ + + if (!mv64xxx_find_baud_factors(bus_freq, tclk, diff --git a/queue-3.16/i2c-rcar-fix-mnr-interrupt-handling.patch b/queue-3.16/i2c-rcar-fix-mnr-interrupt-handling.patch new file mode 100644 index 00000000000..a257713bf34 --- /dev/null +++ b/queue-3.16/i2c-rcar-fix-mnr-interrupt-handling.patch @@ -0,0 +1,63 @@ +From dd318b0df27c582ac0d72a346fd6e693700be23c Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Tue, 2 Sep 2014 01:15:26 +0400 +Subject: i2c: rcar: fix MNR interrupt handling + +From: Sergei Shtylyov + +commit dd318b0df27c582ac0d72a346fd6e693700be23c upstream. + +Sometimes the MNR and MST interrupts happen simultaneously (stop automatically +follows NACK, according to the manuals) and in such case the ID_NACK flag isn't +set since the MST interrupt handling precedes MNR and all interrupts are cleared +and disabled then, so that MNR interrupt is never noticed -- this causes NACK'ed +transfers to be falsely reported as successful. Exchanging MNR and MST handlers +fixes this issue, however the MNR bit somehow gets set again even after being +explicitly cleared, so I decided to completely suppress handling of all disabled +interrupts (which is a good thing anyway)... + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -372,18 +372,15 @@ static irqreturn_t rcar_i2c_irq(int irq, + + msr = rcar_i2c_read(priv, ICMSR); + ++ /* Only handle interrupts that are currently enabled */ ++ msr &= rcar_i2c_read(priv, ICMIER); ++ + /* Arbitration lost */ + if (msr & MAL) { + rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST)); + goto out; + } + +- /* Stop */ +- if (msr & MST) { +- rcar_i2c_flags_set(priv, ID_DONE); +- goto out; +- } +- + /* Nack */ + if (msr & MNR) { + /* go to stop phase */ +@@ -393,6 +390,12 @@ static irqreturn_t rcar_i2c_irq(int irq, + goto out; + } + ++ /* Stop */ ++ if (msr & MST) { ++ rcar_i2c_flags_set(priv, ID_DONE); ++ goto out; ++ } ++ + if (rcar_i2c_is_recv(priv)) + rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); + else diff --git a/queue-3.16/i2c-rcar-fix-rcar_irq_ack_-recv-send.patch b/queue-3.16/i2c-rcar-fix-rcar_irq_ack_-recv-send.patch new file mode 100644 index 00000000000..f0177dbe761 --- /dev/null +++ b/queue-3.16/i2c-rcar-fix-rcar_irq_ack_-recv-send.patch @@ -0,0 +1,34 @@ +From 938916fbb8e8cb67eacb784f4eda17e2950c16c5 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Sat, 6 Sep 2014 03:34:32 +0400 +Subject: i2c: rcar: fix RCAR_IRQ_ACK_{RECV|SEND} + +From: Sergei Shtylyov + +commit 938916fbb8e8cb67eacb784f4eda17e2950c16c5 upstream. + +Bits 8-31 of all registers reflect the value of bits 0-7 on reads and should be +0 on writes, according to the manuals. RCAR_IRQ_ACK_{RECV|SEND} macros have all +1's in bits 8-31, thus going against the manuals, so fix them. + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -76,8 +76,8 @@ + #define RCAR_IRQ_RECV (MNR | MAL | MST | MAT | MDR) + #define RCAR_IRQ_STOP (MST) + +-#define RCAR_IRQ_ACK_SEND (~(MAT | MDE)) +-#define RCAR_IRQ_ACK_RECV (~(MAT | MDR)) ++#define RCAR_IRQ_ACK_SEND (~(MAT | MDE) & 0xFF) ++#define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0xFF) + + #define ID_LAST_MSG (1 << 0) + #define ID_IOERROR (1 << 1) diff --git a/queue-3.16/i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch b/queue-3.16/i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch new file mode 100644 index 00000000000..37033da69c4 --- /dev/null +++ b/queue-3.16/i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch @@ -0,0 +1,38 @@ +From 5da4309f9e1b4de9c2b69e917912fbb84006d44e Mon Sep 17 00:00:00 2001 +From: addy ke +Date: Sat, 23 Aug 2014 02:00:52 +0800 +Subject: i2c: rk3x: fix bug that cause transfer fails in master receive mode + +From: addy ke + +commit 5da4309f9e1b4de9c2b69e917912fbb84006d44e upstream. + +In rk3x SOC, the I2C controller can receive/transmit up to 32 bytes data +in one chunk, so the size of data to be write/read to/from TXDATAx/RXDATAx +must be less than or equal 32 bytes at a time. + +Tested on rk3288-pinky board, elan receive 158 bytes data. + +Signed-off-by: Addy Ke +Acked-by: Max Schwarz +Reviewed-by: Doug Anderson +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rk3x.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/i2c/busses/i2c-rk3x.c ++++ b/drivers/i2c/busses/i2c-rk3x.c +@@ -323,6 +323,10 @@ static void rk3x_i2c_handle_read(struct + /* ack interrupt */ + i2c_writel(i2c, REG_INT_MBRF, REG_IPD); + ++ /* Can only handle a maximum of 32 bytes at a time */ ++ if (len > 32) ++ len = 32; ++ + /* read the data from receive buffer */ + for (i = 0; i < len; ++i) { + if (i % 4 == 0) diff --git a/queue-3.16/i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch b/queue-3.16/i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch new file mode 100644 index 00000000000..387a50f8fbf --- /dev/null +++ b/queue-3.16/i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch @@ -0,0 +1,49 @@ +From b4a7bd7a386dc6b0bb49cb47614e06e8295d495a Mon Sep 17 00:00:00 2001 +From: addy ke +Date: Mon, 8 Sep 2014 11:38:25 +0800 +Subject: i2c: rk3x: fix divisor calculation for SCL frequency + +From: addy ke + +commit b4a7bd7a386dc6b0bb49cb47614e06e8295d495a upstream. + +I2C_CLKDIV register descripted in the previous version of +RK3x chip manual is incorrect. Plus 1 is required. + +The correct formula: +- T(SCL_HIGH) = T(PCLK) * (CLKDIVH + 1) * 8 +- T(SCL_LOW) = T(PCLK) * (CLKDIVL + 1) * 8 +- (SCL Divsor) = 8 * ((CLKDIVL + 1) + (CLKDIVH + 1)) +- SCL = PCLK / (CLK Divsor) + +It will be updated to the latest version of chip manual. + +Signed-off-by: Addy Ke +Reviewed-by: Doug Anderson +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rk3x.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/drivers/i2c/busses/i2c-rk3x.c ++++ b/drivers/i2c/busses/i2c-rk3x.c +@@ -433,12 +433,11 @@ static void rk3x_i2c_set_scl_rate(struct + unsigned long i2c_rate = clk_get_rate(i2c->clk); + unsigned int div; + +- /* SCL rate = (clk rate) / (8 * DIV) */ +- div = DIV_ROUND_UP(i2c_rate, scl_rate * 8); +- +- /* The lower and upper half of the CLKDIV reg describe the length of +- * SCL low & high periods. */ +- div = DIV_ROUND_UP(div, 2); ++ /* set DIV = DIVH = DIVL ++ * SCL rate = (clk rate) / (8 * (DIVH + 1 + DIVL + 1)) ++ * = (clk rate) / (16 * (DIV + 1)) ++ */ ++ div = DIV_ROUND_UP(i2c_rate, scl_rate * 16) - 1; + + i2c_writel(i2c, (div << 16) | (div & 0xffff), REG_CLKDIV); + } diff --git a/queue-3.16/revert-i2c-rcar-remove-spinlock.patch b/queue-3.16/revert-i2c-rcar-remove-spinlock.patch new file mode 100644 index 00000000000..551807d94fe --- /dev/null +++ b/queue-3.16/revert-i2c-rcar-remove-spinlock.patch @@ -0,0 +1,110 @@ +From 91bfe2989af02e709ca01ccf518c4fbda3efc70f Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Sun, 24 Aug 2014 00:44:09 +0400 +Subject: Revert "i2c: rcar: remove spinlock" + +From: Sergei Shtylyov + +commit 91bfe2989af02e709ca01ccf518c4fbda3efc70f upstream. + +This reverts commit 150b8be3cda54412ad7b54f5392b513b25c0aaa7. + +The I2C core's per-adapter locks can't protect from IRQs, so the driver still +needs a spinlock to protect the register accesses. + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-rcar.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + /* register offsets */ + #define ICSCR 0x00 /* slave ctrl */ +@@ -95,6 +96,7 @@ struct rcar_i2c_priv { + struct i2c_msg *msg; + struct clk *clk; + ++ spinlock_t lock; + wait_queue_head_t wait; + + int pos; +@@ -365,6 +367,9 @@ static irqreturn_t rcar_i2c_irq(int irq, + struct rcar_i2c_priv *priv = ptr; + u32 msr; + ++ /*-------------- spin lock -----------------*/ ++ spin_lock(&priv->lock); ++ + msr = rcar_i2c_read(priv, ICMSR); + + /* Arbitration lost */ +@@ -400,6 +405,9 @@ out: + wake_up(&priv->wait); + } + ++ spin_unlock(&priv->lock); ++ /*-------------- spin unlock -----------------*/ ++ + return IRQ_HANDLED; + } + +@@ -409,14 +417,21 @@ static int rcar_i2c_master_xfer(struct i + { + struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); + struct device *dev = rcar_i2c_priv_to_dev(priv); ++ unsigned long flags; + int i, ret, timeout; + + pm_runtime_get_sync(dev); + ++ /*-------------- spin lock -----------------*/ ++ spin_lock_irqsave(&priv->lock, flags); ++ + rcar_i2c_init(priv); + /* start clock */ + rcar_i2c_write(priv, ICCCR, priv->icccr); + ++ spin_unlock_irqrestore(&priv->lock, flags); ++ /*-------------- spin unlock -----------------*/ ++ + ret = rcar_i2c_bus_barrier(priv); + if (ret < 0) + goto out; +@@ -428,6 +443,9 @@ static int rcar_i2c_master_xfer(struct i + break; + } + ++ /*-------------- spin lock -----------------*/ ++ spin_lock_irqsave(&priv->lock, flags); ++ + /* init each data */ + priv->msg = &msgs[i]; + priv->pos = 0; +@@ -437,6 +455,9 @@ static int rcar_i2c_master_xfer(struct i + + ret = rcar_i2c_prepare_msg(priv); + ++ spin_unlock_irqrestore(&priv->lock, flags); ++ /*-------------- spin unlock -----------------*/ ++ + if (ret < 0) + break; + +@@ -540,6 +561,7 @@ static int rcar_i2c_probe(struct platfor + + irq = platform_get_irq(pdev, 0); + init_waitqueue_head(&priv->wait); ++ spin_lock_init(&priv->lock); + + adap = &priv->adap; + adap->nr = pdev->id; diff --git a/queue-3.16/series b/queue-3.16/series index 1fa4988b089..c86126fe65e 100644 --- a/queue-3.16/series +++ b/queue-3.16/series @@ -41,3 +41,12 @@ arm64-flush-tls-registers-during-exec.patch arm64-use-irq_set_affinity-with-force-false-when-migrating-irqs.patch arm-arm64-kvm-complete-wfi-wfe-instructions.patch arm-arm64-kvm-nuke-hyp-mode-tlbs-before-enabling-mmu.patch +i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch +i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch +i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch +i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch +revert-i2c-rcar-remove-spinlock.patch +i2c-rcar-fix-mnr-interrupt-handling.patch +i2c-rcar-fix-rcar_irq_ack_-recv-send.patch +i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch +i2c-ismt-use-correct-length-when-copy-buffer.patch -- 2.47.3