Commit 6fb98fb3 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman

serial: core: Use proper spinlock flavor in uart_close()

uart_close() runs in non-atomic context only; use
spin_lock/unlock_irq instead of saving the interrupt state (which
== on).
Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2a0e5ef6
...@@ -1377,7 +1377,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1377,7 +1377,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
struct uart_state *state = tty->driver_data; struct uart_state *state = tty->driver_data;
struct tty_port *port; struct tty_port *port;
struct uart_port *uport; struct uart_port *uport;
unsigned long flags;
if (!state) { if (!state) {
struct uart_driver *drv = tty->driver->driver_state; struct uart_driver *drv = tty->driver->driver_state;
...@@ -1403,10 +1402,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1403,10 +1402,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* disable the receive line status interrupts. * disable the receive line status interrupts.
*/ */
if (port->flags & ASYNC_INITIALIZED) { if (port->flags & ASYNC_INITIALIZED) {
unsigned long flags; spin_lock_irq(&uport->lock);
spin_lock_irqsave(&uport->lock, flags);
uport->ops->stop_rx(uport); uport->ops->stop_rx(uport);
spin_unlock_irqrestore(&uport->lock, flags); spin_unlock_irq(&uport->lock);
/* /*
* Before we drop DTR, make sure the UART transmitter * Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially * has completely drained; this is especially
...@@ -1419,17 +1417,17 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1419,17 +1417,17 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
uart_shutdown(tty, state); uart_shutdown(tty, state);
tty_port_tty_set(port, NULL); tty_port_tty_set(port, NULL);
spin_lock_irqsave(&port->lock, flags); spin_lock_irq(&port->lock);
if (port->blocked_open) { if (port->blocked_open) {
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irq(&port->lock);
if (port->close_delay) if (port->close_delay)
msleep_interruptible(jiffies_to_msecs(port->close_delay)); msleep_interruptible(jiffies_to_msecs(port->close_delay));
spin_lock_irqsave(&port->lock, flags); spin_lock_irq(&port->lock);
} else if (!uart_console(uport)) { } else if (!uart_console(uport)) {
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irq(&port->lock);
uart_change_pm(state, UART_PM_STATE_OFF); uart_change_pm(state, UART_PM_STATE_OFF);
spin_lock_irqsave(&port->lock, flags); spin_lock_irq(&port->lock);
} }
/* /*
...@@ -1437,7 +1435,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1437,7 +1435,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
*/ */
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
clear_bit(ASYNCB_CLOSING, &port->flags); clear_bit(ASYNCB_CLOSING, &port->flags);
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irq(&port->lock);
wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&port->close_wait); wake_up_interruptible(&port->close_wait);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment