]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Aug 2013 01:04:06 +0000 (09:04 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Aug 2013 01:04:06 +0000 (09:04 +0800)
added patches:
alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch
atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch
dma-pl330-fix-cyclic-transfers.patch
serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch
serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch

queue-3.4/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch [new file with mode: 0644]
queue-3.4/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch [new file with mode: 0644]
queue-3.4/dma-pl330-fix-cyclic-transfers.patch [new file with mode: 0644]
queue-3.4/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch [new file with mode: 0644]
queue-3.4/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch b/queue-3.4/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch
new file mode 100644 (file)
index 0000000..181a81a
--- /dev/null
@@ -0,0 +1,33 @@
+From a8d30608eaed6cc759b8e2e8a8bbbb42591f797f Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Mon, 29 Jul 2013 15:10:22 +0530
+Subject: ALSA: compress: fix the return value for SNDRV_COMPRESS_VERSION
+
+From: Vinod Koul <vinod.koul@intel.com>
+
+commit a8d30608eaed6cc759b8e2e8a8bbbb42591f797f upstream.
+
+the return value of SNDRV_COMPRESS_VERSION always return default -ENOTTY as the
+return value was never updated for this call
+assign return value from put_user()
+
+Reported-by: Haynes <hgeorge@codeaurora.org>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/compress_offload.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/core/compress_offload.c
++++ b/sound/core/compress_offload.c
+@@ -582,7 +582,7 @@ static long snd_compr_ioctl(struct file
+       mutex_lock(&stream->device->lock);
+       switch (_IOC_NR(cmd)) {
+       case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
+-              put_user(SNDRV_COMPRESS_VERSION,
++              retval = put_user(SNDRV_COMPRESS_VERSION,
+                               (int __user *)arg) ? -EFAULT : 0;
+               break;
+       case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
diff --git a/queue-3.4/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch b/queue-3.4/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch
new file mode 100644 (file)
index 0000000..70a8e13
--- /dev/null
@@ -0,0 +1,44 @@
+From ebe7fdbaf3e90ea22feade6c9f5e50f42b23b6d8 Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@tuxdriver.com>
+Date: Fri, 26 Jul 2013 12:47:14 -0400
+Subject: atl1c: Fix misuse of netdev_alloc_skb in refilling rx ring
+
+From: Neil Horman <nhorman@tuxdriver.com>
+
+commit ebe7fdbaf3e90ea22feade6c9f5e50f42b23b6d8 upstream.
+
+atl1c uses netdev_alloc_skb to refill its rx dma ring, but that call makes no
+guarantees about the suitability of the memory for use in DMA.  As a result
+we've gotten reports of atl1c drivers occasionally hanging and needing to be
+reset:
+https://bugzilla.kernel.org/show_bug.cgi?id=54021
+
+Fix this by modifying the call to use the internal version __netdev_alloc_skb,
+where you can set the gfp_mask explicitly to include GFP_DMA.
+
+Tested by two reporters in the above bug, who have the hardware to validate it.
+Both report immediate cessation of the problem with this patch
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+CC: Jay Cliburn <jcliburn@gmail.com>
+CC: "David S. Miller" <davem@davemloft.net>
+Tested-by: Luis Henriques <luis.henriques@canonical.com>
+Tested-by: Vincent Alquier <vincent.alquier@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/atheros/atl1c/atl1c_main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+@@ -1765,7 +1765,7 @@ static int atl1c_alloc_rx_buffer(struct
+       while (next_info->flags & ATL1C_BUFFER_FREE) {
+               rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
+-              skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len);
++              skb = __netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len, GFP_ATOMIC|GFP_DMA);
+               if (unlikely(!skb)) {
+                       if (netif_msg_rx_err(adapter))
+                               dev_warn(&pdev->dev, "alloc rx buffer failed\n");
diff --git a/queue-3.4/dma-pl330-fix-cyclic-transfers.patch b/queue-3.4/dma-pl330-fix-cyclic-transfers.patch
new file mode 100644 (file)
index 0000000..f113d7d
--- /dev/null
@@ -0,0 +1,144 @@
+From fc51446021f42aca8906e701fc2292965aafcb15 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Tue, 23 Jul 2013 10:24:50 +0200
+Subject: dma: pl330: Fix cyclic transfers
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit fc51446021f42aca8906e701fc2292965aafcb15 upstream.
+
+Allocate a descriptor for each period of a cyclic transfer, not just the first.
+Also since the callback needs to be called for each finished period make sure to
+initialize the callback and callback_param fields of each descriptor in a cyclic
+transfer.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dma/pl330.c |   93 +++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 67 insertions(+), 26 deletions(-)
+
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -2511,6 +2511,10 @@ static dma_cookie_t pl330_tx_submit(stru
+       /* Assign cookies to all nodes */
+       while (!list_empty(&last->node)) {
+               desc = list_entry(last->node.next, struct dma_pl330_desc, node);
++              if (pch->cyclic) {
++                      desc->txd.callback = last->txd.callback;
++                      desc->txd.callback_param = last->txd.callback_param;
++              }
+               dma_cookie_assign(&desc->txd);
+@@ -2694,45 +2698,82 @@ static struct dma_async_tx_descriptor *p
+               size_t period_len, enum dma_transfer_direction direction,
+               void *context)
+ {
+-      struct dma_pl330_desc *desc;
++      struct dma_pl330_desc *desc = NULL, *first = NULL;
+       struct dma_pl330_chan *pch = to_pchan(chan);
++      struct dma_pl330_dmac *pdmac = pch->dmac;
++      unsigned int i;
+       dma_addr_t dst;
+       dma_addr_t src;
+-      desc = pl330_get_desc(pch);
+-      if (!desc) {
+-              dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+-                      __func__, __LINE__);
++      if (len % period_len != 0)
+               return NULL;
+-      }
+-      switch (direction) {
+-      case DMA_MEM_TO_DEV:
+-              desc->rqcfg.src_inc = 1;
+-              desc->rqcfg.dst_inc = 0;
+-              desc->req.rqtype = MEMTODEV;
+-              src = dma_addr;
+-              dst = pch->fifo_addr;
+-              break;
+-      case DMA_DEV_TO_MEM:
+-              desc->rqcfg.src_inc = 0;
+-              desc->rqcfg.dst_inc = 1;
+-              desc->req.rqtype = DEVTOMEM;
+-              src = pch->fifo_addr;
+-              dst = dma_addr;
+-              break;
+-      default:
++      if (!is_slave_direction(direction)) {
+               dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
+               __func__, __LINE__);
+               return NULL;
+       }
+-      desc->rqcfg.brst_size = pch->burst_sz;
+-      desc->rqcfg.brst_len = 1;
++      for (i = 0; i < len / period_len; i++) {
++              desc = pl330_get_desc(pch);
++              if (!desc) {
++                      dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
++                              __func__, __LINE__);
+-      pch->cyclic = true;
++                      if (!first)
++                              return NULL;
++
++                      spin_lock_irqsave(&pdmac->pool_lock, flags);
++
++                      while (!list_empty(&first->node)) {
++                              desc = list_entry(first->node.next,
++                                              struct dma_pl330_desc, node);
++                              list_move_tail(&desc->node, &pdmac->desc_pool);
++                      }
++
++                      list_move_tail(&first->node, &pdmac->desc_pool);
++
++                      spin_unlock_irqrestore(&pdmac->pool_lock, flags);
++
++                      return NULL;
++              }
++
++              switch (direction) {
++              case DMA_MEM_TO_DEV:
++                      desc->rqcfg.src_inc = 1;
++                      desc->rqcfg.dst_inc = 0;
++                      desc->req.rqtype = MEMTODEV;
++                      src = dma_addr;
++                      dst = pch->fifo_addr;
++                      break;
++              case DMA_DEV_TO_MEM:
++                      desc->rqcfg.src_inc = 0;
++                      desc->rqcfg.dst_inc = 1;
++                      desc->req.rqtype = DEVTOMEM;
++                      src = pch->fifo_addr;
++                      dst = dma_addr;
++                      break;
++              default:
++                      break;
++              }
+-      fill_px(&desc->px, dst, src, period_len);
++              desc->rqcfg.brst_size = pch->burst_sz;
++              desc->rqcfg.brst_len = 1;
++              fill_px(&desc->px, dst, src, period_len);
++
++              if (!first)
++                      first = desc;
++              else
++                      list_add_tail(&desc->node, &first->node);
++
++              dma_addr += period_len;
++      }
++
++      if (!desc)
++              return NULL;
++
++      pch->cyclic = true;
++      desc->txd.flags = flags;
+       return &desc->txd;
+ }
diff --git a/queue-3.4/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch b/queue-3.4/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch
new file mode 100644 (file)
index 0000000..5cbce47
--- /dev/null
@@ -0,0 +1,60 @@
+From d970d7fe65adff5efe75b4a73c4ffc9be57089f7 Mon Sep 17 00:00:00 2001
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Date: Thu, 4 Jul 2013 11:28:51 +0200
+Subject: serial/mxs-auart: fix race condition in interrupt handler
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+commit d970d7fe65adff5efe75b4a73c4ffc9be57089f7 upstream.
+
+The handler needs to ack the pending events before actually handling them.
+Otherwise a new event might come in after it it considered non-pending or
+handled and is acked then without being handled. So this event is only
+noticed when the next interrupt happens.
+
+Without this patch an i.MX28 based machine running an rt-patched kernel
+regularly hangs during boot.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/mxs-auart.c |   17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/serial/mxs-auart.c
++++ b/drivers/tty/serial/mxs-auart.c
+@@ -375,11 +375,18 @@ static void mxs_auart_settermios(struct
+ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
+ {
+-      u32 istatus, istat;
++      u32 istat;
+       struct mxs_auart_port *s = context;
+       u32 stat = readl(s->port.membase + AUART_STAT);
+-      istatus = istat = readl(s->port.membase + AUART_INTR);
++      istat = readl(s->port.membase + AUART_INTR);
++
++      /* ack irq */
++      writel(istat & (AUART_INTR_RTIS
++              | AUART_INTR_TXIS
++              | AUART_INTR_RXIS
++              | AUART_INTR_CTSMIS),
++                      s->port.membase + AUART_INTR_CLR);
+       if (istat & AUART_INTR_CTSMIS) {
+               uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
+@@ -398,12 +405,6 @@ static irqreturn_t mxs_auart_irq_handle(
+               istat &= ~AUART_INTR_TXIS;
+       }
+-      writel(istatus & (AUART_INTR_RTIS
+-              | AUART_INTR_TXIS
+-              | AUART_INTR_RXIS
+-              | AUART_INTR_CTSMIS),
+-                      s->port.membase + AUART_INTR_CLR);
+-
+       return IRQ_HANDLED;
+ }
diff --git a/queue-3.4/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch b/queue-3.4/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch
new file mode 100644 (file)
index 0000000..522eb4a
--- /dev/null
@@ -0,0 +1,71 @@
+From 079a036f4283e2b0e5c26080b8c5112bc0cc1831 Mon Sep 17 00:00:00 2001
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Date: Fri, 28 Jun 2013 11:49:41 +0200
+Subject: serial/mxs-auart: increase time to wait for transmitter to become idle
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+commit 079a036f4283e2b0e5c26080b8c5112bc0cc1831 upstream.
+
+Without this patch the driver waits ~1 ms for the UART to become idle. At
+115200n8 this time is (theoretically) enough to transfer 11.5 characters
+(= 115200 bits/s / (10 Bits/char) * 1ms). As the mxs-auart has a fifo size
+of 16 characters the clock is gated too early. The problem is worse for
+lower baud rates.
+
+This only happens to really shut down the transmitter in the middle of a
+transfer if /dev/ttyAPPx isn't opened in userspace (e.g. by a getty) but
+was at least once (because the bootloader doesn't disable the transmitter).
+
+So increase the timeout to 20 ms which should be enough for 9600n8, too.
+Moreover skip gating the clock if the timeout is elapsed.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/mxs-auart.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/serial/mxs-auart.c
++++ b/drivers/tty/serial/mxs-auart.c
+@@ -544,7 +544,7 @@ auart_console_write(struct console *co,
+       struct mxs_auart_port *s;
+       struct uart_port *port;
+       unsigned int old_ctrl0, old_ctrl2;
+-      unsigned int to = 1000;
++      unsigned int to = 20000;
+       if (co->index > MXS_AUART_PORTS || co->index < 0)
+               return;
+@@ -565,18 +565,23 @@ auart_console_write(struct console *co,
+       uart_console_write(port, str, count, mxs_auart_console_putchar);
+-      /*
+-       * Finally, wait for transmitter to become empty
+-       * and restore the TCR
+-       */
++      /* Finally, wait for transmitter to become empty ... */
+       while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
++              udelay(1);
+               if (!to--)
+                       break;
+-              udelay(1);
+       }
+-      writel(old_ctrl0, port->membase + AUART_CTRL0);
+-      writel(old_ctrl2, port->membase + AUART_CTRL2);
++      /*
++       * ... and restore the TCR if we waited long enough for the transmitter
++       * to be idle. This might keep the transmitter enabled although it is
++       * unused, but that is better than to disable it while it is still
++       * transmitting.
++       */
++      if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) {
++              writel(old_ctrl0, port->membase + AUART_CTRL0);
++              writel(old_ctrl2, port->membase + AUART_CTRL2);
++      }
+       clk_disable(s->clk);
+ }
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8f0ba0797fd7889eb0f9e31b49bf12f39aa39b06 100644 (file)
@@ -0,0 +1,5 @@
+alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch
+serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch
+serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch
+dma-pl330-fix-cyclic-transfers.patch
+atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch