From 18639db64ff6585d4be91f9645674957feb01452 Mon Sep 17 00:00:00 2001 From: Matson Hall Date: Wed, 26 Sep 2012 15:23:20 +0200 Subject: [PATCH] tty: sunxi-8250: fix something in the hackery with more hackery --- drivers/tty/serial/8250/8250.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index ef5bcd957ae25a..d6daf8ff07227b 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -1524,9 +1524,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) struct uart_8250_port *up = container_of(port, struct uart_8250_port, port); - if (iir & UART_IIR_NO_INT) - return 0; - + if (! (iir & UART_IIR_NO_INT)) { spin_lock_irqsave(&port->lock, flags); status = serial_port_in(port, UART_LSR); @@ -1541,6 +1539,25 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) spin_unlock_irqrestore(&port->lock, flags); return 1; + } else if ((up->port.iotype == UPIO_MEM32) && + (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { + /* The DesignWare APB UART has an Busy Detect (0x07) + * interrupt meaning an LCR write attempt occurred while the + * UART was busy. The interrupt must be cleared by reading + * the UART status register (USR) and the LCR re-written. */ + unsigned int mcr_t = serial_in(up, UART_MCR); + printk(">>> ttyS%d bus busy...\n", up->port.line); + //status = *(volatile u32 *)up->port.private_data; + serial_out(up, UART_MCR, mcr_t|(1<<4)); //to loopback mode + while(serial_in(up, UART_USR)&1) + serial_in(up, UART_RX); + serial_out(up, UART_LCR, up->lcr); + serial_out(up, UART_MCR, mcr_t); //to normal mode + + return 1; + } + + return 0; } EXPORT_SYMBOL_GPL(serial8250_handle_irq);