diff options
-rw-r--r-- | drivers/serial/serial_core.c | 88 |
1 files changed, 33 insertions, 55 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 047530b285bb..fa4f170f2e86 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -2006,12 +2006,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2006 | 2006 | ||
2007 | mutex_lock(&port->mutex); | 2007 | mutex_lock(&port->mutex); |
2008 | 2008 | ||
2009 | if (!console_suspend_enabled && uart_console(uport)) { | ||
2010 | /* we're going to avoid suspending serial console */ | ||
2011 | mutex_unlock(&port->mutex); | ||
2012 | return 0; | ||
2013 | } | ||
2014 | |||
2015 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); | 2009 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
2016 | if (device_may_wakeup(tty_dev)) { | 2010 | if (device_may_wakeup(tty_dev)) { |
2017 | enable_irq_wake(uport->irq); | 2011 | enable_irq_wake(uport->irq); |
@@ -2019,20 +2013,23 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2019 | mutex_unlock(&port->mutex); | 2013 | mutex_unlock(&port->mutex); |
2020 | return 0; | 2014 | return 0; |
2021 | } | 2015 | } |
2022 | uport->suspended = 1; | 2016 | if (console_suspend_enabled || !uart_console(uport)) |
2017 | uport->suspended = 1; | ||
2023 | 2018 | ||
2024 | if (port->flags & ASYNC_INITIALIZED) { | 2019 | if (port->flags & ASYNC_INITIALIZED) { |
2025 | const struct uart_ops *ops = uport->ops; | 2020 | const struct uart_ops *ops = uport->ops; |
2026 | int tries; | 2021 | int tries; |
2027 | 2022 | ||
2028 | set_bit(ASYNCB_SUSPENDED, &port->flags); | 2023 | if (console_suspend_enabled || !uart_console(uport)) { |
2029 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 2024 | set_bit(ASYNCB_SUSPENDED, &port->flags); |
2025 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | ||
2030 | 2026 | ||
2031 | spin_lock_irq(&uport->lock); | 2027 | spin_lock_irq(&uport->lock); |
2032 | ops->stop_tx(uport); | 2028 | ops->stop_tx(uport); |
2033 | ops->set_mctrl(uport, 0); | 2029 | ops->set_mctrl(uport, 0); |
2034 | ops->stop_rx(uport); | 2030 | ops->stop_rx(uport); |
2035 | spin_unlock_irq(&uport->lock); | 2031 | spin_unlock_irq(&uport->lock); |
2032 | } | ||
2036 | 2033 | ||
2037 | /* | 2034 | /* |
2038 | * Wait for the transmitter to empty. | 2035 | * Wait for the transmitter to empty. |
@@ -2047,16 +2044,18 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2047 | drv->dev_name, | 2044 | drv->dev_name, |
2048 | drv->tty_driver->name_base + uport->line); | 2045 | drv->tty_driver->name_base + uport->line); |
2049 | 2046 | ||
2050 | ops->shutdown(uport); | 2047 | if (console_suspend_enabled || !uart_console(uport)) |
2048 | ops->shutdown(uport); | ||
2051 | } | 2049 | } |
2052 | 2050 | ||
2053 | /* | 2051 | /* |
2054 | * Disable the console device before suspending. | 2052 | * Disable the console device before suspending. |
2055 | */ | 2053 | */ |
2056 | if (uart_console(uport)) | 2054 | if (console_suspend_enabled && uart_console(uport)) |
2057 | console_stop(uport->cons); | 2055 | console_stop(uport->cons); |
2058 | 2056 | ||
2059 | uart_change_pm(state, 3); | 2057 | if (console_suspend_enabled || !uart_console(uport)) |
2058 | uart_change_pm(state, 3); | ||
2060 | 2059 | ||
2061 | mutex_unlock(&port->mutex); | 2060 | mutex_unlock(&port->mutex); |
2062 | 2061 | ||
@@ -2073,29 +2072,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2073 | 2072 | ||
2074 | mutex_lock(&port->mutex); | 2073 | mutex_lock(&port->mutex); |
2075 | 2074 | ||
2076 | if (!console_suspend_enabled && uart_console(uport)) { | ||
2077 | /* no need to resume serial console, it wasn't suspended */ | ||
2078 | /* | ||
2079 | * First try to use the console cflag setting. | ||
2080 | */ | ||
2081 | memset(&termios, 0, sizeof(struct ktermios)); | ||
2082 | termios.c_cflag = uport->cons->cflag; | ||
2083 | /* | ||
2084 | * If that's unset, use the tty termios setting. | ||
2085 | */ | ||
2086 | if (termios.c_cflag == 0) | ||
2087 | termios = *state->port.tty->termios; | ||
2088 | else { | ||
2089 | termios.c_ispeed = termios.c_ospeed = | ||
2090 | tty_termios_input_baud_rate(&termios); | ||
2091 | termios.c_ispeed = termios.c_ospeed = | ||
2092 | tty_termios_baud_rate(&termios); | ||
2093 | } | ||
2094 | uport->ops->set_termios(uport, &termios, NULL); | ||
2095 | mutex_unlock(&port->mutex); | ||
2096 | return 0; | ||
2097 | } | ||
2098 | |||
2099 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); | 2075 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
2100 | if (!uport->suspended && device_may_wakeup(tty_dev)) { | 2076 | if (!uport->suspended && device_may_wakeup(tty_dev)) { |
2101 | disable_irq_wake(uport->irq); | 2077 | disable_irq_wake(uport->irq); |
@@ -2121,21 +2097,23 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2121 | spin_lock_irq(&uport->lock); | 2097 | spin_lock_irq(&uport->lock); |
2122 | ops->set_mctrl(uport, 0); | 2098 | ops->set_mctrl(uport, 0); |
2123 | spin_unlock_irq(&uport->lock); | 2099 | spin_unlock_irq(&uport->lock); |
2124 | ret = ops->startup(uport); | 2100 | if (console_suspend_enabled || !uart_console(uport)) { |
2125 | if (ret == 0) { | 2101 | ret = ops->startup(uport); |
2126 | uart_change_speed(state, NULL); | 2102 | if (ret == 0) { |
2127 | spin_lock_irq(&uport->lock); | 2103 | uart_change_speed(state, NULL); |
2128 | ops->set_mctrl(uport, uport->mctrl); | 2104 | spin_lock_irq(&uport->lock); |
2129 | ops->start_tx(uport); | 2105 | ops->set_mctrl(uport, uport->mctrl); |
2130 | spin_unlock_irq(&uport->lock); | 2106 | ops->start_tx(uport); |
2131 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 2107 | spin_unlock_irq(&uport->lock); |
2132 | } else { | 2108 | set_bit(ASYNCB_INITIALIZED, &port->flags); |
2133 | /* | 2109 | } else { |
2134 | * Failed to resume - maybe hardware went away? | 2110 | /* |
2135 | * Clear the "initialized" flag so we won't try | 2111 | * Failed to resume - maybe hardware went away? |
2136 | * to call the low level drivers shutdown method. | 2112 | * Clear the "initialized" flag so we won't try |
2137 | */ | 2113 | * to call the low level drivers shutdown method. |
2138 | uart_shutdown(state); | 2114 | */ |
2115 | uart_shutdown(state); | ||
2116 | } | ||
2139 | } | 2117 | } |
2140 | 2118 | ||
2141 | clear_bit(ASYNCB_SUSPENDED, &port->flags); | 2119 | clear_bit(ASYNCB_SUSPENDED, &port->flags); |