Commit 3689a0ec authored by George G. Davis's avatar George G. Davis Committed by Linus Torvalds

[PATCH] serial: make sure UART is powered up when dumping MCTRL status

Since serial devices are powered down when not in use and some of those
devices cannot be accessed when powered down, we need to enable power
around calls to get_mcrtl() when dumping port state via uart_line_info().
This resolves hangs observed on some machines while reading serial device
registers when a port is powered off.
Signed-off-by: default avatarGeorge G. Davis <gdavis@mvista.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9b22271d
...@@ -1660,6 +1660,7 @@ static const char *uart_type(struct uart_port *port) ...@@ -1660,6 +1660,7 @@ static const char *uart_type(struct uart_port *port)
static int uart_line_info(char *buf, struct uart_driver *drv, int i) static int uart_line_info(char *buf, struct uart_driver *drv, int i)
{ {
struct uart_state *state = drv->state + i; struct uart_state *state = drv->state + i;
int pm_state;
struct uart_port *port = state->port; struct uart_port *port = state->port;
char stat_buf[32]; char stat_buf[32];
unsigned int status; unsigned int status;
...@@ -1682,9 +1683,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) ...@@ -1682,9 +1683,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
if(capable(CAP_SYS_ADMIN)) if(capable(CAP_SYS_ADMIN))
{ {
mutex_lock(&state->mutex);
pm_state = state->pm_state;
if (pm_state)
uart_change_pm(state, 0);
spin_lock_irq(&port->lock); spin_lock_irq(&port->lock);
status = port->ops->get_mctrl(port); status = port->ops->get_mctrl(port);
spin_unlock_irq(&port->lock); spin_unlock_irq(&port->lock);
if (pm_state)
uart_change_pm(state, pm_state);
mutex_unlock(&state->mutex);
ret += sprintf(buf + ret, " tx:%d rx:%d", ret += sprintf(buf + ret, " tx:%d rx:%d",
port->icount.tx, port->icount.rx); port->icount.tx, port->icount.rx);
...@@ -2100,6 +2108,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, ...@@ -2100,6 +2108,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
uart_report_port(drv, port); uart_report_port(drv, port);
/* Power up port for set_mctrl() */
uart_change_pm(state, 0);
/* /*
* Ensure that the modem control lines are de-activated. * Ensure that the modem control lines are de-activated.
* We probably don't need a spinlock around this, but * We probably don't need a spinlock around this, but
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment