From: Greg Kroah-Hartman Date: Mon, 5 Aug 2013 01:04:06 +0000 (+0800) Subject: 3.4-stable patches X-Git-Tag: v3.0.90~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea17536635ca13067c0b08f8a72b7121a18d4f92;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches 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 --- 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 index 00000000000..181a81a8a66 --- /dev/null +++ b/queue-3.4/alsa-compress-fix-the-return-value-for-sndrv_compress_version.patch @@ -0,0 +1,33 @@ +From a8d30608eaed6cc759b8e2e8a8bbbb42591f797f Mon Sep 17 00:00:00 2001 +From: Vinod Koul +Date: Mon, 29 Jul 2013 15:10:22 +0530 +Subject: ALSA: compress: fix the return value for SNDRV_COMPRESS_VERSION + +From: Vinod Koul + +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 +Signed-off-by: Vinod Koul +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..70a8e13397e --- /dev/null +++ b/queue-3.4/atl1c-fix-misuse-of-netdev_alloc_skb-in-refilling-rx-ring.patch @@ -0,0 +1,44 @@ +From ebe7fdbaf3e90ea22feade6c9f5e50f42b23b6d8 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Fri, 26 Jul 2013 12:47:14 -0400 +Subject: atl1c: Fix misuse of netdev_alloc_skb in refilling rx ring + +From: Neil Horman + +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 +CC: Jay Cliburn +CC: "David S. Miller" +Tested-by: Luis Henriques +Tested-by: Vincent Alquier +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f113d7d5873 --- /dev/null +++ b/queue-3.4/dma-pl330-fix-cyclic-transfers.patch @@ -0,0 +1,144 @@ +From fc51446021f42aca8906e701fc2292965aafcb15 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen +Date: Tue, 23 Jul 2013 10:24:50 +0200 +Subject: dma: pl330: Fix cyclic transfers + +From: Lars-Peter Clausen + +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 +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5cbce4791bd --- /dev/null +++ b/queue-3.4/serial-mxs-auart-fix-race-condition-in-interrupt-handler.patch @@ -0,0 +1,60 @@ +From d970d7fe65adff5efe75b4a73c4ffc9be57089f7 Mon Sep 17 00:00:00 2001 +From: Uwe Kleine-König +Date: Thu, 4 Jul 2013 11:28:51 +0200 +Subject: serial/mxs-auart: fix race condition in interrupt handler + +From: Uwe Kleine-König + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..522eb4aba90 --- /dev/null +++ b/queue-3.4/serial-mxs-auart-increase-time-to-wait-for-transmitter-to-become-idle.patch @@ -0,0 +1,71 @@ +From 079a036f4283e2b0e5c26080b8c5112bc0cc1831 Mon Sep 17 00:00:00 2001 +From: Uwe Kleine-König +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } diff --git a/queue-3.4/series b/queue-3.4/series index e69de29bb2d..8f0ba0797fd 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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