diff options
| -rw-r--r-- | Documentation/serial/driver | 5 | ||||
| -rw-r--r-- | drivers/tty/serial/serial_core.c | 30 | ||||
| -rw-r--r-- | include/linux/serial_core.h | 14 |
3 files changed, 31 insertions, 18 deletions
diff --git a/Documentation/serial/driver b/Documentation/serial/driver index 0a25a9191864..a6ef8dc436f1 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver | |||
| @@ -242,9 +242,8 @@ hardware. | |||
| 242 | 242 | ||
| 243 | pm(port,state,oldstate) | 243 | pm(port,state,oldstate) |
| 244 | Perform any power management related activities on the specified | 244 | Perform any power management related activities on the specified |
| 245 | port. State indicates the new state (defined by ACPI D0-D3), | 245 | port. State indicates the new state (defined by |
| 246 | oldstate indicates the previous state. Essentially, D0 means | 246 | enum uart_pm_state), oldstate indicates the previous state. |
| 247 | fully on, D3 means powered down. | ||
| 248 | 247 | ||
| 249 | This function should not be used to grab any resources. | 248 | This function should not be used to grab any resources. |
| 250 | 249 | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2c7230aaefd4..82d7ce8c9409 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
| @@ -59,7 +59,8 @@ static struct lock_class_key port_lock_key; | |||
| 59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
| 60 | struct ktermios *old_termios); | 60 | struct ktermios *old_termios); |
| 61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); | 61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); |
| 62 | static void uart_change_pm(struct uart_state *state, int pm_state); | 62 | static void uart_change_pm(struct uart_state *state, |
| 63 | enum uart_pm_state pm_state); | ||
| 63 | 64 | ||
| 64 | static void uart_port_shutdown(struct tty_port *port); | 65 | static void uart_port_shutdown(struct tty_port *port); |
| 65 | 66 | ||
| @@ -1365,7 +1366,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
| 1365 | spin_lock_irqsave(&port->lock, flags); | 1366 | spin_lock_irqsave(&port->lock, flags); |
| 1366 | } else if (!uart_console(uport)) { | 1367 | } else if (!uart_console(uport)) { |
| 1367 | spin_unlock_irqrestore(&port->lock, flags); | 1368 | spin_unlock_irqrestore(&port->lock, flags); |
| 1368 | uart_change_pm(state, 3); | 1369 | uart_change_pm(state, UART_PM_STATE_OFF); |
| 1369 | spin_lock_irqsave(&port->lock, flags); | 1370 | spin_lock_irqsave(&port->lock, flags); |
| 1370 | } | 1371 | } |
| 1371 | 1372 | ||
| @@ -1579,7 +1580,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
| 1579 | * Make sure the device is in D0 state. | 1580 | * Make sure the device is in D0 state. |
| 1580 | */ | 1581 | */ |
| 1581 | if (port->count == 1) | 1582 | if (port->count == 1) |
| 1582 | uart_change_pm(state, 0); | 1583 | uart_change_pm(state, UART_PM_STATE_ON); |
| 1583 | 1584 | ||
| 1584 | /* | 1585 | /* |
| 1585 | * Start up the serial port. | 1586 | * Start up the serial port. |
| @@ -1620,7 +1621,7 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
| 1620 | { | 1621 | { |
| 1621 | struct uart_state *state = drv->state + i; | 1622 | struct uart_state *state = drv->state + i; |
| 1622 | struct tty_port *port = &state->port; | 1623 | struct tty_port *port = &state->port; |
| 1623 | int pm_state; | 1624 | enum uart_pm_state pm_state; |
| 1624 | struct uart_port *uport = state->uart_port; | 1625 | struct uart_port *uport = state->uart_port; |
| 1625 | char stat_buf[32]; | 1626 | char stat_buf[32]; |
| 1626 | unsigned int status; | 1627 | unsigned int status; |
| @@ -1645,12 +1646,12 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
| 1645 | if (capable(CAP_SYS_ADMIN)) { | 1646 | if (capable(CAP_SYS_ADMIN)) { |
| 1646 | mutex_lock(&port->mutex); | 1647 | mutex_lock(&port->mutex); |
| 1647 | pm_state = state->pm_state; | 1648 | pm_state = state->pm_state; |
| 1648 | if (pm_state) | 1649 | if (pm_state != UART_PM_STATE_ON) |
| 1649 | uart_change_pm(state, 0); | 1650 | uart_change_pm(state, UART_PM_STATE_ON); |
| 1650 | spin_lock_irq(&uport->lock); | 1651 | spin_lock_irq(&uport->lock); |
| 1651 | status = uport->ops->get_mctrl(uport); | 1652 | status = uport->ops->get_mctrl(uport); |
| 1652 | spin_unlock_irq(&uport->lock); | 1653 | spin_unlock_irq(&uport->lock); |
| 1653 | if (pm_state) | 1654 | if (pm_state != UART_PM_STATE_ON) |
| 1654 | uart_change_pm(state, pm_state); | 1655 | uart_change_pm(state, pm_state); |
| 1655 | mutex_unlock(&port->mutex); | 1656 | mutex_unlock(&port->mutex); |
| 1656 | 1657 | ||
| @@ -1897,7 +1898,8 @@ EXPORT_SYMBOL_GPL(uart_set_options); | |||
| 1897 | * | 1898 | * |
| 1898 | * Locking: port->mutex has to be held | 1899 | * Locking: port->mutex has to be held |
| 1899 | */ | 1900 | */ |
| 1900 | static void uart_change_pm(struct uart_state *state, int pm_state) | 1901 | static void uart_change_pm(struct uart_state *state, |
| 1902 | enum uart_pm_state pm_state) | ||
| 1901 | { | 1903 | { |
| 1902 | struct uart_port *port = state->uart_port; | 1904 | struct uart_port *port = state->uart_port; |
| 1903 | 1905 | ||
| @@ -1982,7 +1984,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
| 1982 | console_stop(uport->cons); | 1984 | console_stop(uport->cons); |
| 1983 | 1985 | ||
| 1984 | if (console_suspend_enabled || !uart_console(uport)) | 1986 | if (console_suspend_enabled || !uart_console(uport)) |
| 1985 | uart_change_pm(state, 3); | 1987 | uart_change_pm(state, UART_PM_STATE_OFF); |
| 1986 | 1988 | ||
| 1987 | mutex_unlock(&port->mutex); | 1989 | mutex_unlock(&port->mutex); |
| 1988 | 1990 | ||
| @@ -2027,7 +2029,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
| 2027 | termios = port->tty->termios; | 2029 | termios = port->tty->termios; |
| 2028 | 2030 | ||
| 2029 | if (console_suspend_enabled) | 2031 | if (console_suspend_enabled) |
| 2030 | uart_change_pm(state, 0); | 2032 | uart_change_pm(state, UART_PM_STATE_ON); |
| 2031 | uport->ops->set_termios(uport, &termios, NULL); | 2033 | uport->ops->set_termios(uport, &termios, NULL); |
| 2032 | if (console_suspend_enabled) | 2034 | if (console_suspend_enabled) |
| 2033 | console_start(uport->cons); | 2035 | console_start(uport->cons); |
| @@ -2037,7 +2039,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
| 2037 | const struct uart_ops *ops = uport->ops; | 2039 | const struct uart_ops *ops = uport->ops; |
| 2038 | int ret; | 2040 | int ret; |
| 2039 | 2041 | ||
| 2040 | uart_change_pm(state, 0); | 2042 | uart_change_pm(state, UART_PM_STATE_ON); |
| 2041 | spin_lock_irq(&uport->lock); | 2043 | spin_lock_irq(&uport->lock); |
| 2042 | ops->set_mctrl(uport, 0); | 2044 | ops->set_mctrl(uport, 0); |
| 2043 | spin_unlock_irq(&uport->lock); | 2045 | spin_unlock_irq(&uport->lock); |
| @@ -2137,7 +2139,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
| 2137 | uart_report_port(drv, port); | 2139 | uart_report_port(drv, port); |
| 2138 | 2140 | ||
| 2139 | /* Power up port for set_mctrl() */ | 2141 | /* Power up port for set_mctrl() */ |
| 2140 | uart_change_pm(state, 0); | 2142 | uart_change_pm(state, UART_PM_STATE_ON); |
| 2141 | 2143 | ||
| 2142 | /* | 2144 | /* |
| 2143 | * Ensure that the modem control lines are de-activated. | 2145 | * Ensure that the modem control lines are de-activated. |
| @@ -2161,7 +2163,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
| 2161 | * console if we have one. | 2163 | * console if we have one. |
| 2162 | */ | 2164 | */ |
| 2163 | if (!uart_console(port)) | 2165 | if (!uart_console(port)) |
| 2164 | uart_change_pm(state, 3); | 2166 | uart_change_pm(state, UART_PM_STATE_OFF); |
| 2165 | } | 2167 | } |
| 2166 | } | 2168 | } |
| 2167 | 2169 | ||
| @@ -2588,7 +2590,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
| 2588 | } | 2590 | } |
| 2589 | 2591 | ||
| 2590 | state->uart_port = uport; | 2592 | state->uart_port = uport; |
| 2591 | state->pm_state = -1; | 2593 | state->pm_state = UART_PM_STATE_UNDEFINED; |
| 2592 | 2594 | ||
| 2593 | uport->cons = drv->cons; | 2595 | uport->cons = drv->cons; |
| 2594 | uport->state = state; | 2596 | uport->state = state; |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index c6690a2a27fb..a116daa13113 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
| @@ -208,13 +208,25 @@ static inline void serial_port_out(struct uart_port *up, int offset, int value) | |||
| 208 | up->serial_out(up, offset, value); | 208 | up->serial_out(up, offset, value); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | /** | ||
| 212 | * enum uart_pm_state - power states for UARTs | ||
| 213 | * @UART_PM_STATE_ON: UART is powered, up and operational | ||
| 214 | * @UART_PM_STATE_OFF: UART is powered off | ||
| 215 | * @UART_PM_STATE_UNDEFINED: sentinel | ||
| 216 | */ | ||
| 217 | enum uart_pm_state { | ||
| 218 | UART_PM_STATE_ON = 0, | ||
| 219 | UART_PM_STATE_OFF = 3, /* number taken from ACPI */ | ||
| 220 | UART_PM_STATE_UNDEFINED, | ||
| 221 | }; | ||
| 222 | |||
| 211 | /* | 223 | /* |
| 212 | * This is the state information which is persistent across opens. | 224 | * This is the state information which is persistent across opens. |
| 213 | */ | 225 | */ |
| 214 | struct uart_state { | 226 | struct uart_state { |
| 215 | struct tty_port port; | 227 | struct tty_port port; |
| 216 | 228 | ||
| 217 | int pm_state; | 229 | enum uart_pm_state pm_state; |
| 218 | struct circ_buf xmit; | 230 | struct circ_buf xmit; |
| 219 | 231 | ||
| 220 | struct uart_port *uart_port; | 232 | struct uart_port *uart_port; |
