diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2010-12-13 14:16:17 +0530 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2010-12-13 05:01:17 -0800 |
commit | 91cc72c93ee826d6d9406dfeffdbf0a70d1581ed (patch) | |
tree | e989c3f0ca7ade929d4e01a005eb545cc0e9da6f /drivers/serial | |
parent | 3f8643777020580015f71f59c25b07aad43e0103 (diff) |
[armi]tegra: serial: Removing tx workqueue.
Following are changes:
- Removed the tx workqueue and start next trsnafer in tx dma
complete callback only.
- Remove the wait for tx fifo empty before starting next transfer.
The uart controller req dma/gen interrupt only when trigger level
reached.
bug 765172
Change-Id: I1cc9c528451c7d0f733c16c8b64ca79cdab31d64
Reviewed-on: http://git-master/r/12697
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/tegra_hsuart.c | 45 |
1 files changed, 9 insertions, 36 deletions
diff --git a/drivers/serial/tegra_hsuart.c b/drivers/serial/tegra_hsuart.c index 09f5f454683c..3c8e83b807b9 100644 --- a/drivers/serial/tegra_hsuart.c +++ b/drivers/serial/tegra_hsuart.c @@ -107,7 +107,6 @@ struct tegra_uart_port { /* TX DMA */ struct tegra_dma_req tx_dma_req; struct tegra_dma_channel *tx_dma; - struct work_struct tx_work; /* RX DMA */ struct tegra_dma_req rx_dma_req; @@ -411,34 +410,6 @@ static void do_handle_tx_pio(struct tegra_uart_port *t) return; } -static void tegra_tx_dma_complete_work(struct work_struct *work) -{ - struct tegra_uart_port *t = - container_of(work, struct tegra_uart_port, tx_work); - struct tegra_dma_req *req = &t->tx_dma_req; - unsigned long flags; - int timeout = 20; - - while ((uart_readb(t, UART_LSR) & TX_EMPTY_STATUS) != TX_EMPTY_STATUS) { - timeout--; - if (timeout == 0) { - dev_err(t->uport.dev, - "timed out waiting for TX FIFO to empty\n"); - return; - } - msleep(1); - } - - spin_lock_irqsave(&t->uport.lock, flags); - - t->tx_in_progress = 0; - - if (req->status != -TEGRA_DMA_REQ_ERROR_ABORTED) - tegra_start_next_tx(t); - - spin_unlock_irqrestore(&t->uport.lock, flags); -} - static void tegra_tx_dma_complete_callback(struct tegra_dma_req *req) { struct tegra_uart_port *t = req->dev; @@ -450,11 +421,13 @@ static void tegra_tx_dma_complete_callback(struct tegra_dma_req *req) spin_lock_irqsave(&t->uport.lock, flags); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); + t->tx_in_progress = 0; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&t->uport); - schedule_work(&t->tx_work); + if (req->status != -TEGRA_DMA_REQ_ERROR_ABORTED) + tegra_start_next_tx(t); spin_unlock_irqrestore(&t->uport.lock, flags); } @@ -561,8 +534,6 @@ static void tegra_uart_hw_deinit(struct tegra_uart_port *t) unsigned char fcr; unsigned long flags; - flush_work(&t->tx_work); - /* Disable interrupts */ uart_writeb(t, 0, UART_IER); @@ -939,13 +910,17 @@ static unsigned int tegra_tx_empty(struct uart_port *u) struct tegra_uart_port *t; unsigned int ret = 0; unsigned long flags; + unsigned char lsr; t = container_of(u, struct tegra_uart_port, uport); dev_vdbg(u->dev, "+tegra_tx_empty\n"); spin_lock_irqsave(&u->lock, flags); - if (!t->tx_in_progress) - ret = TIOCSER_TEMT; + if (!t->tx_in_progress) { + lsr = uart_readb(t, UART_LSR); + if ((lsr & TX_EMPTY_STATUS) == TX_EMPTY_STATUS) + ret = TIOCSER_TEMT; + } spin_unlock_irqrestore(&u->lock, flags); dev_vdbg(u->dev, "-tegra_tx_empty\n"); @@ -1180,7 +1155,6 @@ static int tegra_uart_suspend(struct platform_device *pdev, pm_message_t state) u = &t->uport; uart_suspend_port(&tegra_uart_driver, u); - flush_work(&t->tx_work); return 0; } @@ -1277,7 +1251,6 @@ static int tegra_uart_probe(struct platform_device *pdev) pr_info("Registered UART port %s%d\n", tegra_uart_driver.dev_name, u->line); - INIT_WORK(&t->tx_work, tegra_tx_dma_complete_work); return ret; fail: kfree(t); |