aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge G. Davis <gdavis@mvista.com>2007-02-14 03:33:06 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-14 11:09:52 -0500
commit3689a0ec60bc8f56cc372c1dfa0d89dab48f7c9c (patch)
tree2481249f304a34fbff2db433b955178face86026
parent9b22271d4b8c1be8a81563c322d3f04e7cbe2153 (diff)
[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: George G. Davis <gdavis@mvista.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/serial/serial_core.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index f84982e508c7..66fdd3b2b958 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1660,6 +1660,7 @@ static const char *uart_type(struct uart_port *port)
1660static int uart_line_info(char *buf, struct uart_driver *drv, int i) 1660static int uart_line_info(char *buf, struct uart_driver *drv, int i)
1661{ 1661{
1662 struct uart_state *state = drv->state + i; 1662 struct uart_state *state = drv->state + i;
1663 int pm_state;
1663 struct uart_port *port = state->port; 1664 struct uart_port *port = state->port;
1664 char stat_buf[32]; 1665 char stat_buf[32];
1665 unsigned int status; 1666 unsigned int status;
@@ -1682,9 +1683,16 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
1682 1683
1683 if(capable(CAP_SYS_ADMIN)) 1684 if(capable(CAP_SYS_ADMIN))
1684 { 1685 {
1686 mutex_lock(&state->mutex);
1687 pm_state = state->pm_state;
1688 if (pm_state)
1689 uart_change_pm(state, 0);
1685 spin_lock_irq(&port->lock); 1690 spin_lock_irq(&port->lock);
1686 status = port->ops->get_mctrl(port); 1691 status = port->ops->get_mctrl(port);
1687 spin_unlock_irq(&port->lock); 1692 spin_unlock_irq(&port->lock);
1693 if (pm_state)
1694 uart_change_pm(state, pm_state);
1695 mutex_unlock(&state->mutex);
1688 1696
1689 ret += sprintf(buf + ret, " tx:%d rx:%d", 1697 ret += sprintf(buf + ret, " tx:%d rx:%d",
1690 port->icount.tx, port->icount.rx); 1698 port->icount.tx, port->icount.rx);
@@ -2100,6 +2108,9 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
2100 2108
2101 uart_report_port(drv, port); 2109 uart_report_port(drv, port);
2102 2110
2111 /* Power up port for set_mctrl() */
2112 uart_change_pm(state, 0);
2113
2103 /* 2114 /*
2104 * Ensure that the modem control lines are de-activated. 2115 * Ensure that the modem control lines are de-activated.
2105 * We probably don't need a spinlock around this, but 2116 * We probably don't need a spinlock around this, but