diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2009-01-02 08:40:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:34 -0500 |
commit | 68a784cb1add52543644a879ef601f3b52d18623 (patch) | |
tree | 88f4cd4a729a48edace500c8d164f4c01c443712 /drivers | |
parent | b6efa1eabbe8d23fd7dcad1eed8ce945f4adea83 (diff) |
Blackfin Serial Driver: Fix bug - BF527-EZKIT unable to receive large files over UART in DMA mode
Add spin_lock_irqsave() when receive and transfer data.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/serial/bfin_5xx.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 88449d36a3f7..1c85039d021f 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -81,7 +81,9 @@ static void bfin_serial_reset_irda(struct uart_port *port); | |||
81 | static void bfin_serial_stop_tx(struct uart_port *port) | 81 | static void bfin_serial_stop_tx(struct uart_port *port) |
82 | { | 82 | { |
83 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 83 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
84 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
84 | struct circ_buf *xmit = &uart->port.info->xmit; | 85 | struct circ_buf *xmit = &uart->port.info->xmit; |
86 | #endif | ||
85 | 87 | ||
86 | while (!(UART_GET_LSR(uart) & TEMT)) | 88 | while (!(UART_GET_LSR(uart) & TEMT)) |
87 | cpu_relax(); | 89 | cpu_relax(); |
@@ -412,7 +414,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
412 | 414 | ||
413 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | 415 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) |
414 | { | 416 | { |
415 | int x_pos, pos; | 417 | int x_pos, pos, flags; |
418 | |||
419 | spin_lock_irqsave(&uart->port.lock, flags); | ||
416 | 420 | ||
417 | uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel); | 421 | uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel); |
418 | x_pos = get_dma_curr_xcount(uart->rx_dma_channel); | 422 | x_pos = get_dma_curr_xcount(uart->rx_dma_channel); |
@@ -430,6 +434,8 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
430 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; | 434 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; |
431 | } | 435 | } |
432 | 436 | ||
437 | spin_unlock_irqrestore(&uart->port.lock, flags); | ||
438 | |||
433 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 439 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
434 | } | 440 | } |
435 | 441 | ||
@@ -464,10 +470,9 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) | |||
464 | spin_lock(&uart->port.lock); | 470 | spin_lock(&uart->port.lock); |
465 | irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); | 471 | irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); |
466 | clear_dma_irqstat(uart->rx_dma_channel); | 472 | clear_dma_irqstat(uart->rx_dma_channel); |
473 | bfin_serial_dma_rx_chars(uart); | ||
467 | spin_unlock(&uart->port.lock); | 474 | spin_unlock(&uart->port.lock); |
468 | 475 | ||
469 | mod_timer(&(uart->rx_dma_timer), jiffies); | ||
470 | |||
471 | return IRQ_HANDLED; | 476 | return IRQ_HANDLED; |
472 | } | 477 | } |
473 | #endif | 478 | #endif |