8250: fix autoconfig to work with serial console
The autoconfig prints messages while holding the port's spinlock and that causes a deadlock when using serial console. Signed-off-by: Flavio Leitner <fbl@redhat.com> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
05fb79e45e
commit
bd21f551c3
|
@ -1037,6 +1037,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
|
||||||
unsigned char save_lcr, save_mcr;
|
unsigned char save_lcr, save_mcr;
|
||||||
struct uart_port *port = &up->port;
|
struct uart_port *port = &up->port;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
unsigned int old_capabilities;
|
||||||
|
|
||||||
if (!port->iobase && !port->mapbase && !port->membase)
|
if (!port->iobase && !port->mapbase && !port->membase)
|
||||||
return;
|
return;
|
||||||
|
@ -1087,6 +1088,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
|
||||||
/*
|
/*
|
||||||
* We failed; there's nothing here
|
* We failed; there's nothing here
|
||||||
*/
|
*/
|
||||||
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
|
DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
|
||||||
scratch2, scratch3);
|
scratch2, scratch3);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1110,6 +1112,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
|
||||||
status1 = serial_in(up, UART_MSR) & 0xF0;
|
status1 = serial_in(up, UART_MSR) & 0xF0;
|
||||||
serial_out(up, UART_MCR, save_mcr);
|
serial_out(up, UART_MCR, save_mcr);
|
||||||
if (status1 != 0x90) {
|
if (status1 != 0x90) {
|
||||||
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
DEBUG_AUTOCONF("LOOP test failed (%02x) ",
|
DEBUG_AUTOCONF("LOOP test failed (%02x) ",
|
||||||
status1);
|
status1);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1132,8 +1135,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
|
||||||
serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
|
serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
|
||||||
scratch = serial_in(up, UART_IIR) >> 6;
|
scratch = serial_in(up, UART_IIR) >> 6;
|
||||||
|
|
||||||
DEBUG_AUTOCONF("iir=%d ", scratch);
|
|
||||||
|
|
||||||
switch (scratch) {
|
switch (scratch) {
|
||||||
case 0:
|
case 0:
|
||||||
autoconfig_8250(up);
|
autoconfig_8250(up);
|
||||||
|
@ -1167,19 +1168,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
|
||||||
|
|
||||||
serial_out(up, UART_LCR, save_lcr);
|
serial_out(up, UART_LCR, save_lcr);
|
||||||
|
|
||||||
if (up->capabilities != uart_config[port->type].flags) {
|
|
||||||
printk(KERN_WARNING
|
|
||||||
"ttyS%d: detected caps %08x should be %08x\n",
|
|
||||||
serial_index(port), up->capabilities,
|
|
||||||
uart_config[port->type].flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
port->fifosize = uart_config[up->port.type].fifo_size;
|
port->fifosize = uart_config[up->port.type].fifo_size;
|
||||||
|
old_capabilities = up->capabilities;
|
||||||
up->capabilities = uart_config[port->type].flags;
|
up->capabilities = uart_config[port->type].flags;
|
||||||
up->tx_loadsz = uart_config[port->type].tx_loadsz;
|
up->tx_loadsz = uart_config[port->type].tx_loadsz;
|
||||||
|
|
||||||
if (port->type == PORT_UNKNOWN)
|
if (port->type == PORT_UNKNOWN)
|
||||||
goto out;
|
goto out_lock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the UART.
|
* Reset the UART.
|
||||||
|
@ -1196,8 +1191,16 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
|
||||||
else
|
else
|
||||||
serial_out(up, UART_IER, 0);
|
serial_out(up, UART_IER, 0);
|
||||||
|
|
||||||
out:
|
out_lock:
|
||||||
spin_unlock_irqrestore(&port->lock, flags);
|
spin_unlock_irqrestore(&port->lock, flags);
|
||||||
|
if (up->capabilities != old_capabilities) {
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"ttyS%d: detected caps %08x should be %08x\n",
|
||||||
|
serial_index(port), old_capabilities,
|
||||||
|
up->capabilities);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
DEBUG_AUTOCONF("iir=%d ", scratch);
|
||||||
DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name);
|
DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue