diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-01-25 09:52:48 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-01-25 09:52:48 -0500 |
commit | f1487fcbe47cd2bc0c71e8598bf9eb6a82dec544 (patch) | |
tree | 4c7abed6047538c13dd024a8ecffd15f31b4609a /drivers/serial/serial_core.c | |
parent | 84549d239ab9bb2e3a85c6efcf0e6478a38b4260 (diff) | |
parent | 40aa7030e5213a43e9e0554fd7f95534ea310bf3 (diff) |
Merge branch 'for-2.6.33' into for-2.6.34
Diffstat (limited to 'drivers/serial/serial_core.c')
-rw-r--r-- | drivers/serial/serial_core.c | 105 |
1 files changed, 45 insertions, 60 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 047530b285b..7f283070951 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -385,13 +385,20 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, | |||
385 | } | 385 | } |
386 | 386 | ||
387 | /* | 387 | /* |
388 | * As a last resort, if the quotient is zero, | 388 | * As a last resort, if the range cannot be met then clip to |
389 | * default to 9600 bps | 389 | * the nearest chip supported rate. |
390 | */ | 390 | */ |
391 | if (!hung_up) | 391 | if (!hung_up) { |
392 | tty_termios_encode_baud_rate(termios, 9600, 9600); | 392 | if (baud <= min) |
393 | tty_termios_encode_baud_rate(termios, | ||
394 | min + 1, min + 1); | ||
395 | else | ||
396 | tty_termios_encode_baud_rate(termios, | ||
397 | max - 1, max - 1); | ||
398 | } | ||
393 | } | 399 | } |
394 | 400 | /* Should never happen */ | |
401 | WARN_ON(1); | ||
395 | return 0; | 402 | return 0; |
396 | } | 403 | } |
397 | 404 | ||
@@ -2006,12 +2013,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2006 | 2013 | ||
2007 | mutex_lock(&port->mutex); | 2014 | mutex_lock(&port->mutex); |
2008 | 2015 | ||
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); | 2016 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
2016 | if (device_may_wakeup(tty_dev)) { | 2017 | if (device_may_wakeup(tty_dev)) { |
2017 | enable_irq_wake(uport->irq); | 2018 | enable_irq_wake(uport->irq); |
@@ -2019,20 +2020,23 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2019 | mutex_unlock(&port->mutex); | 2020 | mutex_unlock(&port->mutex); |
2020 | return 0; | 2021 | return 0; |
2021 | } | 2022 | } |
2022 | uport->suspended = 1; | 2023 | if (console_suspend_enabled || !uart_console(uport)) |
2024 | uport->suspended = 1; | ||
2023 | 2025 | ||
2024 | if (port->flags & ASYNC_INITIALIZED) { | 2026 | if (port->flags & ASYNC_INITIALIZED) { |
2025 | const struct uart_ops *ops = uport->ops; | 2027 | const struct uart_ops *ops = uport->ops; |
2026 | int tries; | 2028 | int tries; |
2027 | 2029 | ||
2028 | set_bit(ASYNCB_SUSPENDED, &port->flags); | 2030 | if (console_suspend_enabled || !uart_console(uport)) { |
2029 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | 2031 | set_bit(ASYNCB_SUSPENDED, &port->flags); |
2032 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | ||
2030 | 2033 | ||
2031 | spin_lock_irq(&uport->lock); | 2034 | spin_lock_irq(&uport->lock); |
2032 | ops->stop_tx(uport); | 2035 | ops->stop_tx(uport); |
2033 | ops->set_mctrl(uport, 0); | 2036 | ops->set_mctrl(uport, 0); |
2034 | ops->stop_rx(uport); | 2037 | ops->stop_rx(uport); |
2035 | spin_unlock_irq(&uport->lock); | 2038 | spin_unlock_irq(&uport->lock); |
2039 | } | ||
2036 | 2040 | ||
2037 | /* | 2041 | /* |
2038 | * Wait for the transmitter to empty. | 2042 | * Wait for the transmitter to empty. |
@@ -2047,16 +2051,18 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
2047 | drv->dev_name, | 2051 | drv->dev_name, |
2048 | drv->tty_driver->name_base + uport->line); | 2052 | drv->tty_driver->name_base + uport->line); |
2049 | 2053 | ||
2050 | ops->shutdown(uport); | 2054 | if (console_suspend_enabled || !uart_console(uport)) |
2055 | ops->shutdown(uport); | ||
2051 | } | 2056 | } |
2052 | 2057 | ||
2053 | /* | 2058 | /* |
2054 | * Disable the console device before suspending. | 2059 | * Disable the console device before suspending. |
2055 | */ | 2060 | */ |
2056 | if (uart_console(uport)) | 2061 | if (console_suspend_enabled && uart_console(uport)) |
2057 | console_stop(uport->cons); | 2062 | console_stop(uport->cons); |
2058 | 2063 | ||
2059 | uart_change_pm(state, 3); | 2064 | if (console_suspend_enabled || !uart_console(uport)) |
2065 | uart_change_pm(state, 3); | ||
2060 | 2066 | ||
2061 | mutex_unlock(&port->mutex); | 2067 | mutex_unlock(&port->mutex); |
2062 | 2068 | ||
@@ -2073,29 +2079,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2073 | 2079 | ||
2074 | mutex_lock(&port->mutex); | 2080 | mutex_lock(&port->mutex); |
2075 | 2081 | ||
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); | 2082 | tty_dev = device_find_child(uport->dev, &match, serial_match_port); |
2100 | if (!uport->suspended && device_may_wakeup(tty_dev)) { | 2083 | if (!uport->suspended && device_may_wakeup(tty_dev)) { |
2101 | disable_irq_wake(uport->irq); | 2084 | disable_irq_wake(uport->irq); |
@@ -2121,21 +2104,23 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2121 | spin_lock_irq(&uport->lock); | 2104 | spin_lock_irq(&uport->lock); |
2122 | ops->set_mctrl(uport, 0); | 2105 | ops->set_mctrl(uport, 0); |
2123 | spin_unlock_irq(&uport->lock); | 2106 | spin_unlock_irq(&uport->lock); |
2124 | ret = ops->startup(uport); | 2107 | if (console_suspend_enabled || !uart_console(uport)) { |
2125 | if (ret == 0) { | 2108 | ret = ops->startup(uport); |
2126 | uart_change_speed(state, NULL); | 2109 | if (ret == 0) { |
2127 | spin_lock_irq(&uport->lock); | 2110 | uart_change_speed(state, NULL); |
2128 | ops->set_mctrl(uport, uport->mctrl); | 2111 | spin_lock_irq(&uport->lock); |
2129 | ops->start_tx(uport); | 2112 | ops->set_mctrl(uport, uport->mctrl); |
2130 | spin_unlock_irq(&uport->lock); | 2113 | ops->start_tx(uport); |
2131 | set_bit(ASYNCB_INITIALIZED, &port->flags); | 2114 | spin_unlock_irq(&uport->lock); |
2132 | } else { | 2115 | set_bit(ASYNCB_INITIALIZED, &port->flags); |
2133 | /* | 2116 | } else { |
2134 | * Failed to resume - maybe hardware went away? | 2117 | /* |
2135 | * Clear the "initialized" flag so we won't try | 2118 | * Failed to resume - maybe hardware went away? |
2136 | * to call the low level drivers shutdown method. | 2119 | * Clear the "initialized" flag so we won't try |
2137 | */ | 2120 | * to call the low level drivers shutdown method. |
2138 | uart_shutdown(state); | 2121 | */ |
2122 | uart_shutdown(state); | ||
2123 | } | ||
2139 | } | 2124 | } |
2140 | 2125 | ||
2141 | clear_bit(ASYNCB_SUSPENDED, &port->flags); | 2126 | clear_bit(ASYNCB_SUSPENDED, &port->flags); |