diff options
Diffstat (limited to 'drivers/serial/serial_core.c')
-rw-r--r-- | drivers/serial/serial_core.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index f84982e508c7..0422c0f1f852 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1523,9 +1523,8 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line) | |||
1523 | } | 1523 | } |
1524 | 1524 | ||
1525 | if (!state->info) { | 1525 | if (!state->info) { |
1526 | state->info = kmalloc(sizeof(struct uart_info), GFP_KERNEL); | 1526 | state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL); |
1527 | if (state->info) { | 1527 | if (state->info) { |
1528 | memset(state->info, 0, sizeof(struct uart_info)); | ||
1529 | init_waitqueue_head(&state->info->open_wait); | 1528 | init_waitqueue_head(&state->info->open_wait); |
1530 | init_waitqueue_head(&state->info->delta_msr_wait); | 1529 | init_waitqueue_head(&state->info->delta_msr_wait); |
1531 | 1530 | ||
@@ -1660,6 +1659,7 @@ static const char *uart_type(struct uart_port *port) | |||
1660 | static int uart_line_info(char *buf, struct uart_driver *drv, int i) | 1659 | static int uart_line_info(char *buf, struct uart_driver *drv, int i) |
1661 | { | 1660 | { |
1662 | struct uart_state *state = drv->state + i; | 1661 | struct uart_state *state = drv->state + i; |
1662 | int pm_state; | ||
1663 | struct uart_port *port = state->port; | 1663 | struct uart_port *port = state->port; |
1664 | char stat_buf[32]; | 1664 | char stat_buf[32]; |
1665 | unsigned int status; | 1665 | unsigned int status; |
@@ -1682,9 +1682,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) | |||
1682 | 1682 | ||
1683 | if(capable(CAP_SYS_ADMIN)) | 1683 | if(capable(CAP_SYS_ADMIN)) |
1684 | { | 1684 | { |
1685 | mutex_lock(&state->mutex); | ||
1686 | pm_state = state->pm_state; | ||
1687 | if (pm_state) | ||
1688 | uart_change_pm(state, 0); | ||
1685 | spin_lock_irq(&port->lock); | 1689 | spin_lock_irq(&port->lock); |
1686 | status = port->ops->get_mctrl(port); | 1690 | status = port->ops->get_mctrl(port); |
1687 | spin_unlock_irq(&port->lock); | 1691 | spin_unlock_irq(&port->lock); |
1692 | if (pm_state) | ||
1693 | uart_change_pm(state, pm_state); | ||
1694 | mutex_unlock(&state->mutex); | ||
1688 | 1695 | ||
1689 | ret += sprintf(buf + ret, " tx:%d rx:%d", | 1696 | ret += sprintf(buf + ret, " tx:%d rx:%d", |
1690 | port->icount.tx, port->icount.rx); | 1697 | port->icount.tx, port->icount.rx); |
@@ -2100,6 +2107,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2100 | 2107 | ||
2101 | uart_report_port(drv, port); | 2108 | uart_report_port(drv, port); |
2102 | 2109 | ||
2110 | /* Power up port for set_mctrl() */ | ||
2111 | uart_change_pm(state, 0); | ||
2112 | |||
2103 | /* | 2113 | /* |
2104 | * Ensure that the modem control lines are de-activated. | 2114 | * Ensure that the modem control lines are de-activated. |
2105 | * We probably don't need a spinlock around this, but | 2115 | * We probably don't need a spinlock around this, but |
@@ -2167,13 +2177,11 @@ int uart_register_driver(struct uart_driver *drv) | |||
2167 | * Maybe we should be using a slab cache for this, especially if | 2177 | * Maybe we should be using a slab cache for this, especially if |
2168 | * we have a large number of ports to handle. | 2178 | * we have a large number of ports to handle. |
2169 | */ | 2179 | */ |
2170 | drv->state = kmalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); | 2180 | drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); |
2171 | retval = -ENOMEM; | 2181 | retval = -ENOMEM; |
2172 | if (!drv->state) | 2182 | if (!drv->state) |
2173 | goto out; | 2183 | goto out; |
2174 | 2184 | ||
2175 | memset(drv->state, 0, sizeof(struct uart_state) * drv->nr); | ||
2176 | |||
2177 | normal = alloc_tty_driver(drv->nr); | 2185 | normal = alloc_tty_driver(drv->nr); |
2178 | if (!normal) | 2186 | if (!normal) |
2179 | goto out; | 2187 | goto out; |