]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 Oct 2014 19:35:37 +0000 (12:35 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 2 Oct 2014 19:35:37 +0000 (12:35 -0700)
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

queue-3.16/i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch [new file with mode: 0644]
queue-3.16/i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch [new file with mode: 0644]
queue-3.16/i2c-ismt-use-correct-length-when-copy-buffer.patch [new file with mode: 0644]
queue-3.16/i2c-mv64xxx-continue-probe-when-clock-frequency-is-missing.patch [new file with mode: 0644]
queue-3.16/i2c-rcar-fix-mnr-interrupt-handling.patch [new file with mode: 0644]
queue-3.16/i2c-rcar-fix-rcar_irq_ack_-recv-send.patch [new file with mode: 0644]
queue-3.16/i2c-rk3x-fix-bug-that-cause-transfer-fails-in-master-receive-mode.patch [new file with mode: 0644]
queue-3.16/i2c-rk3x-fix-divisor-calculation-for-scl-frequency.patch [new file with mode: 0644]
queue-3.16/revert-i2c-rcar-remove-spinlock.patch [new file with mode: 0644]
queue-3.16/series

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 (file)
index 0000000..f247841
--- /dev/null
@@ -0,0 +1,87 @@
+From 75b81f339c6af43f6f4a1b3eabe0603321dade65 Mon Sep 17 00:00:00 2001
+From: Marek Roszko <mark.roszko@gmail.com>
+Date: Wed, 20 Aug 2014 21:39:41 -0400
+Subject: i2c: at91: add bound checking on SMBus block length bytes
+
+From: Marek Roszko <mark.roszko@gmail.com>
+
+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 <mark.roszko@gmail.com>
+Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..0ccff5c
--- /dev/null
@@ -0,0 +1,47 @@
+From 6721f28a26efd6368497abbdef5dcfc59608d899 Mon Sep 17 00:00:00 2001
+From: Simon Lindgren <simon@aqwary.com>
+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 <simon@aqwary.com>
+
+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 <simon@aqwary.com>
+Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..bd1950f
--- /dev/null
@@ -0,0 +1,42 @@
+From 979bbf7b7ae75cfc06e09d09eda38009a3bdc4a4 Mon Sep 17 00:00:00 2001
+From: Fan Du <fan.du@intel.com>
+Date: Tue, 16 Sep 2014 17:21:04 +0800
+Subject: i2c: ismt: use correct length when copy buffer
+
+From: Fan Du <fan.du@intel.com>
+
+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 <fan.du@intel.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a69fc60
--- /dev/null
@@ -0,0 +1,46 @@
+From 0ce4bc1dbdd911ae1763e2d4ff36bd1b214a59f7 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Mon, 1 Sep 2014 22:28:13 +0800
+Subject: i2c: mv64xxx: continue probe when clock-frequency is missing
+
+From: Chen-Yu Tsai <wens@csie.org>
+
+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 <wens@csie.org>
+Acked-by: Andrew Lunn <andrew@lunn.ch>
+Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a257713
--- /dev/null
@@ -0,0 +1,63 @@
+From dd318b0df27c582ac0d72a346fd6e693700be23c Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 2 Sep 2014 01:15:26 +0400
+Subject: i2c: rcar: fix MNR interrupt handling
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+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 <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..f0177db
--- /dev/null
@@ -0,0 +1,34 @@
+From 938916fbb8e8cb67eacb784f4eda17e2950c16c5 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sat, 6 Sep 2014 03:34:32 +0400
+Subject: i2c: rcar: fix RCAR_IRQ_ACK_{RECV|SEND}
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+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 <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..37033da
--- /dev/null
@@ -0,0 +1,38 @@
+From 5da4309f9e1b4de9c2b69e917912fbb84006d44e Mon Sep 17 00:00:00 2001
+From: addy ke <addy.ke@rock-chips.com>
+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 <addy.ke@rock-chips.com>
+
+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 <addy.ke@rock-chips.com>
+Acked-by: Max Schwarz <max.schwarz@online.de>
+Reviewed-by: Doug Anderson <dianders@chromium.org>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..387a50f
--- /dev/null
@@ -0,0 +1,49 @@
+From b4a7bd7a386dc6b0bb49cb47614e06e8295d495a Mon Sep 17 00:00:00 2001
+From: addy ke <addy.ke@rock-chips.com>
+Date: Mon, 8 Sep 2014 11:38:25 +0800
+Subject: i2c: rk3x: fix divisor calculation for SCL frequency
+
+From: addy ke <addy.ke@rock-chips.com>
+
+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 <addy.ke@rock-chips.com>
+Reviewed-by: Doug Anderson <dianders@chromium.org>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..551807d
--- /dev/null
@@ -0,0 +1,110 @@
+From 91bfe2989af02e709ca01ccf518c4fbda3efc70f Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sun, 24 Aug 2014 00:44:09 +0400
+Subject: Revert "i2c: rcar: remove spinlock"
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+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 <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
++#include <linux/spinlock.h>
+ /* 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;
index 1fa4988b089c93b75ecf5c8db2f94589f3e6740d..c86126fe65e9c5bd99670ddc37f113a42c8bda0c 100644 (file)
@@ -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