diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2011-08-22 12:11:35 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:48:37 -0800 |
commit | b1d3eb48c74348a0e1e9b9797d4733c75cfa2df0 (patch) | |
tree | c113f96a9a255684fb11876749e208a12e413060 /drivers/tty | |
parent | eafb921eff957b44434bdd9d0946f8cfa4ff61f5 (diff) |
serial: tegra: Avoid lock in tx dma abort callback
If tx dma is aborted due to some reason like flush buffer, avoiding
lock in tx dma complete callback to avoid the recursive locking.
The caller have already hold the lock in this case.
bug 860574
Original-Change-Id: Iac63fb89ba03a3a89f55b43e823526ecf09d8a1f
Reviewed-on: http://git-master/r/48420
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Tested-by: Laxman Dewangan <ldewangan@nvidia.com>
Rebase-Id: Rd6c0d476be4cef51b948e24ae02db80756e876bb
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/tegra_hsuart.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/tty/serial/tegra_hsuart.c b/drivers/tty/serial/tegra_hsuart.c index 26e9948e6bc1..9b24f2d9adda 100644 --- a/drivers/tty/serial/tegra_hsuart.c +++ b/drivers/tty/serial/tegra_hsuart.c @@ -497,6 +497,13 @@ static void tegra_tx_dma_complete_callback(struct tegra_dma_req *req) dev_vdbg(t->uport.dev, "%s: %d\n", __func__, count); + /* Update xmit pointers without lock if dma aborted. */ + if (req->status == -TEGRA_DMA_REQ_ERROR_ABORTED) { + xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); + t->tx_in_progress = 0; + return; + } + spin_lock_irqsave(&t->uport.lock, flags); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); t->tx_in_progress = 0; @@ -504,8 +511,7 @@ static void tegra_tx_dma_complete_callback(struct tegra_dma_req *req) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&t->uport); - if (req->status != -TEGRA_DMA_REQ_ERROR_ABORTED) - tegra_start_next_tx(t); + tegra_start_next_tx(t); spin_unlock_irqrestore(&t->uport.lock, flags); } |