summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-12-13 14:16:17 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2010-12-13 05:01:17 -0800
commit91cc72c93ee826d6d9406dfeffdbf0a70d1581ed (patch)
treee989c3f0ca7ade929d4e01a005eb545cc0e9da6f /drivers/serial
parent3f8643777020580015f71f59c25b07aad43e0103 (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.c45
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);