diff options
author | Pradeep Goudagunta <pgoudagunta@nvidia.com> | 2011-11-02 18:23:55 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:49:41 -0800 |
commit | 3ff036710d4b1bd74f9cbacb49a87851932e77da (patch) | |
tree | 38a613438f2f95a5f5943d8466eb23278de6801f /drivers/tty | |
parent | 1436142099cebdddbf345584cc8b00f66735e677 (diff) |
tty: serial: tegra: Avoid sleeping in atomic context
Avoid mutex_lock to be called in spin_lock conetxt.
Bug 890147
Reviewed-on: http://git-master/r/59545
(cherry picked from commit 7ebaaea25400d3708b6f3ac3585b61b65ab99a17)
Change-Id: I189dbf1ff3da5e7580b3688680565762fa457f6e
Reviewed-on: http://git-master/r/61871
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Rebase-Id: R167aaab6105b997d4a019c064ee5297e1982c5bb
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/tegra_hsuart.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/tty/serial/tegra_hsuart.c b/drivers/tty/serial/tegra_hsuart.c index 4da1957486b2..87f64146481c 100644 --- a/drivers/tty/serial/tegra_hsuart.c +++ b/drivers/tty/serial/tegra_hsuart.c @@ -633,11 +633,12 @@ static void tegra_uart_hw_deinit(struct tegra_uart_port *t) /* Reset the Rx and Tx FIFOs */ tegra_fifo_reset(t, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); - clk_disable(t->clk); t->baud = 0; t->uart_state = TEGRA_UART_CLOSED; spin_unlock_irqrestore(&t->uport.lock, flags); + + clk_disable(t->clk); } static void tegra_uart_free_rx_dma(struct tegra_uart_port *t) @@ -1233,7 +1234,9 @@ static void tegra_set_termios(struct uart_port *u, struct ktermios *termios, /* Baud rate. */ baud = uart_get_baud_rate(u, termios, oldtermios, 200, 4000000); + spin_unlock_irqrestore(&u->lock, flags); tegra_set_baudrate(t, baud); + spin_lock_irqsave(&u->lock, flags); /* Flow control */ if (termios->c_cflag & CRTSCTS) { @@ -1471,6 +1474,7 @@ void tegra_uart_request_clock_off(struct uart_port *uport) { unsigned long flags; struct tegra_uart_port *t; + bool is_clk_disable = false; if (IS_ERR_OR_NULL(uport)) BUG(); @@ -1480,10 +1484,14 @@ void tegra_uart_request_clock_off(struct uart_port *uport) t = container_of(uport, struct tegra_uart_port, uport); spin_lock_irqsave(&uport->lock, flags); if (t->uart_state == TEGRA_UART_OPENED) { - clk_disable(t->clk); + is_clk_disable = true; t->uart_state = TEGRA_UART_CLOCK_OFF; } spin_unlock_irqrestore(&uport->lock, flags); + + if (is_clk_disable) + clk_disable(t->clk); + return; } @@ -1492,6 +1500,7 @@ void tegra_uart_request_clock_on(struct uart_port *uport) { unsigned long flags; struct tegra_uart_port *t; + bool is_clk_enable = false; if (IS_ERR_OR_NULL(uport)) BUG(); @@ -1499,10 +1508,14 @@ void tegra_uart_request_clock_on(struct uart_port *uport) t = container_of(uport, struct tegra_uart_port, uport); spin_lock_irqsave(&uport->lock, flags); if (t->uart_state == TEGRA_UART_CLOCK_OFF) { - clk_enable(t->clk); + is_clk_enable = true; t->uart_state = TEGRA_UART_OPENED; } spin_unlock_irqrestore(&uport->lock, flags); + + if (is_clk_enable) + clk_enable(t->clk); + return; } |