diff options
Diffstat (limited to 'drivers/tty/serial/bfin_uart.c')
-rw-r--r-- | drivers/tty/serial/bfin_uart.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 9242d56ba267..e6a008f4939f 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | 477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) |
478 | { | 478 | { |
479 | int x_pos, pos; | 479 | int x_pos, pos; |
480 | unsigned long flags; | ||
480 | 481 | ||
481 | dma_disable_irq_nosync(uart->rx_dma_channel); | 482 | spin_lock_irqsave(&uart->rx_lock, flags); |
482 | spin_lock_bh(&uart->rx_lock); | ||
483 | 483 | ||
484 | /* 2D DMA RX buffer ring is used. Because curr_y_count and | 484 | /* 2D DMA RX buffer ring is used. Because curr_y_count and |
485 | * curr_x_count can't be read as an atomic operation, | 485 | * curr_x_count can't be read as an atomic operation, |
@@ -510,8 +510,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | |||
510 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; | 510 | uart->rx_dma_buf.tail = uart->rx_dma_buf.head; |
511 | } | 511 | } |
512 | 512 | ||
513 | spin_unlock_bh(&uart->rx_lock); | 513 | spin_unlock_irqrestore(&uart->rx_lock, flags); |
514 | dma_enable_irq(uart->rx_dma_channel); | ||
515 | 514 | ||
516 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); | 515 | mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); |
517 | } | 516 | } |
@@ -800,6 +799,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
800 | unsigned long flags; | 799 | unsigned long flags; |
801 | unsigned int baud, quot; | 800 | unsigned int baud, quot; |
802 | unsigned int ier, lcr = 0; | 801 | unsigned int ier, lcr = 0; |
802 | unsigned long timeout; | ||
803 | 803 | ||
804 | switch (termios->c_cflag & CSIZE) { | 804 | switch (termios->c_cflag & CSIZE) { |
805 | case CS8: | 805 | case CS8: |
@@ -869,6 +869,14 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, | |||
869 | 869 | ||
870 | UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); | 870 | UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); |
871 | 871 | ||
872 | /* Wait till the transfer buffer is empty */ | ||
873 | timeout = jiffies + msecs_to_jiffies(10); | ||
874 | while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT)) | ||
875 | if (time_after(jiffies, timeout)) { | ||
876 | dev_warn(port->dev, "timeout waiting for TX buffer empty\n"); | ||
877 | break; | ||
878 | } | ||
879 | |||
872 | /* Disable UART */ | 880 | /* Disable UART */ |
873 | ier = UART_GET_IER(uart); | 881 | ier = UART_GET_IER(uart); |
874 | UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN); | 882 | UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN); |
@@ -1390,7 +1398,7 @@ out_error_free_mem: | |||
1390 | return ret; | 1398 | return ret; |
1391 | } | 1399 | } |
1392 | 1400 | ||
1393 | static int __devexit bfin_serial_remove(struct platform_device *pdev) | 1401 | static int bfin_serial_remove(struct platform_device *pdev) |
1394 | { | 1402 | { |
1395 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); | 1403 | struct bfin_serial_port *uart = platform_get_drvdata(pdev); |
1396 | 1404 | ||
@@ -1410,7 +1418,7 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev) | |||
1410 | 1418 | ||
1411 | static struct platform_driver bfin_serial_driver = { | 1419 | static struct platform_driver bfin_serial_driver = { |
1412 | .probe = bfin_serial_probe, | 1420 | .probe = bfin_serial_probe, |
1413 | .remove = __devexit_p(bfin_serial_remove), | 1421 | .remove = bfin_serial_remove, |
1414 | .suspend = bfin_serial_suspend, | 1422 | .suspend = bfin_serial_suspend, |
1415 | .resume = bfin_serial_resume, | 1423 | .resume = bfin_serial_resume, |
1416 | .driver = { | 1424 | .driver = { |