[lkml]   [2011]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[19/53] pch_uart: Fix DMA resource leak issue
3.0-stable review patch.  If anyone has any objections, please let me know.


From: Tomoya MORINAGA <>

commit 90f04c2926cfb5bf74533b0a7766bc896f6a0c0e upstream.

Changing UART mode PIO->DMA->PIO->DMA like below, pch_uart driver can't get
DMA channel resource.

setserial /dev/ttyPCH0 ^low_latency
setserial /dev/ttyPCH0 low_latency

Changing mode using setserial command, ".startup" function which gets DMA
channel is called before ".verify_port" function which sets
dma-flag(use_dma/use_dma_flag) as 1.

.startup: Since dma-flag is 0, DMA channel is not requested.
.verify_port: dma-flag is set as 1.
.shutdown: N/A

.startup: Since dma-flag is 1, DMA channel is requested.
.verify_port: dma-flag is set as 0.
.shutdown: Since dma-flag is 0, DMA channel is not released.

This means DMA channel resource leak occurs.
Next time, this driver can't get DMA channel resource forever.

Currently, when release DMA channel resource, this driver checks dma-flag.
However, this specification occurs the above issue.
This driver must check whether dma_request_channel is executed or not.
The values are saved in private data variable "chan_tx/chan_tx".
These variables mean if the value is NULL, DMA channel is not requested,
if not NULL, DMA channel is requested.

This patch fixes the issue.

Signed-off-by: Tomoya MORINAGA <>
Acked-by: Alan Cox <>
Signed-off-by: Greg Kroah-Hartman <>

drivers/tty/serial/pch_uart.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -625,6 +625,7 @@ static void pch_request_dma(struct uart_
dev_err(priv->, "%s:dma_request_channel FAILS(Rx)\n",
+ priv->chan_tx = NULL;

@@ -1212,8 +1213,7 @@ static void pch_uart_shutdown(struct uar
"pch_uart_hal_set_fifo Failed(ret=%d)\n", ret);

- if (priv->use_dma_flag)
- pch_free_dma(port);
+ pch_free_dma(port);

free_irq(priv->port.irq, priv);

 \ /
  Last update: 2011-11-23 01:43    [W:0.125 / U:23.924 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site