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); |
