]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blobdiff - drivers/tty/serial/bfin_uart.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[can-eth-gw-linux.git] / drivers / tty / serial / bfin_uart.c
index 9b11c3f23eae98fcfad2c97f9983ef5b91928ac1..2e2b2c1cb72252d607dd747305cb354c68dd2cb7 100644 (file)
@@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
 void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
 {
        int x_pos, pos;
+       unsigned long flags;
 
-       dma_disable_irq_nosync(uart->rx_dma_channel);
-       spin_lock_bh(&uart->rx_lock);
+       spin_lock_irqsave(&uart->rx_lock, flags);
 
        /* 2D DMA RX buffer ring is used. Because curr_y_count and
         * 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)
                uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
        }
 
-       spin_unlock_bh(&uart->rx_lock);
-       dma_enable_irq(uart->rx_dma_channel);
+       spin_unlock_irqrestore(&uart->rx_lock, flags);
 
        mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES);
 }
@@ -800,6 +799,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned long flags;
        unsigned int baud, quot;
        unsigned int ier, lcr = 0;
+       unsigned long timeout;
 
        switch (termios->c_cflag & CSIZE) {
        case CS8:
@@ -869,6 +869,14 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
 
        UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
 
+       /* Wait till the transfer buffer is empty */
+       timeout = jiffies + msecs_to_jiffies(10);
+       while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT))
+               if (time_after(jiffies, timeout)) {
+                       dev_warn(port->dev, "timeout waiting for TX buffer empty\n");
+                       break;
+               }
+
        /* Disable UART */
        ier = UART_GET_IER(uart);
        UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
@@ -1390,7 +1398,7 @@ out_error_free_mem:
        return ret;
 }
 
-static int __devexit bfin_serial_remove(struct platform_device *pdev)
+static int bfin_serial_remove(struct platform_device *pdev)
 {
        struct bfin_serial_port *uart = platform_get_drvdata(pdev);
 
@@ -1410,7 +1418,7 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev)
 
 static struct platform_driver bfin_serial_driver = {
        .probe          = bfin_serial_probe,
-       .remove         = __devexit_p(bfin_serial_remove),
+       .remove         = bfin_serial_remove,
        .suspend        = bfin_serial_suspend,
        .resume         = bfin_serial_resume,
        .driver         = {