Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
[firefly-linux-kernel-4.4.55.git] / drivers / tty / serial / 8250.c
index eeadf1b8e093202234b30c688490da2de10a3c04..9f50c4e3c2bea409cf85fb4779475bbad6f7f0c0 100644 (file)
@@ -129,32 +129,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX];
 static unsigned int probe_rsa_count;
 #endif /* CONFIG_SERIAL_8250_RSA  */
 
-struct uart_8250_port {
-       struct uart_port        port;
-       struct timer_list       timer;          /* "no irq" timer */
-       struct list_head        list;           /* ports on this IRQ */
-       unsigned short          capabilities;   /* port capabilities */
-       unsigned short          bugs;           /* port bugs */
-       unsigned int            tx_loadsz;      /* transmit fifo load size */
-       unsigned char           acr;
-       unsigned char           ier;
-       unsigned char           lcr;
-       unsigned char           mcr;
-       unsigned char           mcr_mask;       /* mask of user bits */
-       unsigned char           mcr_force;      /* mask of forced bits */
-       unsigned char           cur_iotype;     /* Running I/O type */
-
-       /*
-        * Some bits in registers are cleared on a read, so they must
-        * be saved whenever the register is read but the bits will not
-        * be immediately processed.
-        */
-#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
-       unsigned char           lsr_saved_flags;
-#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
-       unsigned char           msr_saved_flags;
-};
-
 struct irq_info {
        struct                  hlist_node node;
        int                     irq;
@@ -1326,8 +1300,6 @@ static void serial8250_stop_tx(struct uart_port *port)
        }
 }
 
-static void transmit_chars(struct uart_8250_port *up);
-
 static void serial8250_start_tx(struct uart_port *port)
 {
        struct uart_8250_port *up =
@@ -1344,7 +1316,7 @@ static void serial8250_start_tx(struct uart_port *port)
                        if ((up->port.type == PORT_RM9000) ?
                                (lsr & UART_LSR_THRE) :
                                (lsr & UART_LSR_TEMT))
-                               transmit_chars(up);
+                               serial8250_tx_chars(up);
                }
        }
 
@@ -1401,11 +1373,16 @@ static void clear_rx_fifo(struct uart_8250_port *up)
        } while (1);
 }
 
-static void
-receive_chars(struct uart_8250_port *up, unsigned int *status)
+/*
+ * serial8250_rx_chars: processes according to the passed in LSR
+ * value, and returns the remaining LSR bits not handled
+ * by this Rx routine.
+ */
+unsigned char
+serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
 {
        struct tty_struct *tty = up->port.state->port.tty;
-       unsigned char ch, lsr = *status;
+       unsigned char ch;
        int max_count = 256;
        char flag;
 
@@ -1481,10 +1458,11 @@ ignore_char:
        spin_unlock(&up->port.lock);
        tty_flip_buffer_push(tty);
        spin_lock(&up->port.lock);
-       *status = lsr;
+       return lsr;
 }
+EXPORT_SYMBOL_GPL(serial8250_rx_chars);
 
-static void transmit_chars(struct uart_8250_port *up)
+void serial8250_tx_chars(struct uart_8250_port *up)
 {
        struct circ_buf *xmit = &up->port.state->xmit;
        int count;
@@ -1521,8 +1499,9 @@ static void transmit_chars(struct uart_8250_port *up)
        if (uart_circ_empty(xmit))
                __stop_tx(up);
 }
+EXPORT_SYMBOL_GPL(serial8250_tx_chars);
 
-static unsigned int check_modem_status(struct uart_8250_port *up)
+unsigned int serial8250_modem_status(struct uart_8250_port *up)
 {
        unsigned int status = serial_in(up, UART_MSR);
 
@@ -1544,14 +1523,20 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
 
        return status;
 }
+EXPORT_SYMBOL_GPL(serial8250_modem_status);
 
 /*
  * This handles the interrupt from one port.
  */
-static void serial8250_handle_port(struct uart_8250_port *up)
+int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 {
-       unsigned int status;
+       unsigned char status;
        unsigned long flags;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       if (iir & UART_IIR_NO_INT)
+               return 0;
 
        spin_lock_irqsave(&up->port.lock, flags);
 
@@ -1560,25 +1545,13 @@ static void serial8250_handle_port(struct uart_8250_port *up)
        DEBUG_INTR("status = %x...", status);
 
        if (status & (UART_LSR_DR | UART_LSR_BI))
-               receive_chars(up, &status);
-       check_modem_status(up);
+               status = serial8250_rx_chars(up, status);
+       serial8250_modem_status(up);
        if (status & UART_LSR_THRE)
-               transmit_chars(up);
+               serial8250_tx_chars(up);
 
        spin_unlock_irqrestore(&up->port.lock, flags);
-}
-
-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)) {
-               serial8250_handle_port(up);
-               return 1;
-       }
-
-       return 0;
+       return 1;
 }
 EXPORT_SYMBOL_GPL(serial8250_handle_irq);
 
@@ -1619,11 +1592,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
        do {
                struct uart_8250_port *up;
                struct uart_port *port;
+               bool skip;
 
                up = list_entry(l, struct uart_8250_port, list);
                port = &up->port;
+               skip = pass_counter && up->port.flags & UPF_IIR_ONCE;
 
-               if (port->handle_irq(port)) {
+               if (!skip && port->handle_irq(port)) {
                        handled = 1;
                        end = NULL;
                } else if (end == NULL)
@@ -1758,11 +1733,8 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up)
 static void serial8250_timeout(unsigned long data)
 {
        struct uart_8250_port *up = (struct uart_8250_port *)data;
-       unsigned int iir;
 
-       iir = serial_in(up, UART_IIR);
-       if (!(iir & UART_IIR_NO_INT))
-               serial8250_handle_port(up);
+       up->port.handle_irq(&up->port);
        mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
 }
 
@@ -1801,7 +1773,7 @@ static void serial8250_backup_timeout(unsigned long data)
        }
 
        if (!(iir & UART_IIR_NO_INT))
-               transmit_chars(up);
+               serial8250_tx_chars(up);
 
        if (is_real_interrupt(up->port.irq))
                serial_out(up, UART_IER, ier);
@@ -1835,7 +1807,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
        unsigned int status;
        unsigned int ret;
 
-       status = check_modem_status(up);
+       status = serial8250_modem_status(up);
 
        ret = 0;
        if (status & UART_MSR_DCD)
@@ -2000,7 +1972,7 @@ static int serial8250_startup(struct uart_port *port)
                serial_outp(up, UART_IER, 0);
                serial_outp(up, UART_LCR, 0);
                serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
-               serial_outp(up, UART_LCR, 0xBF);
+               serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
                serial_outp(up, UART_EFR, UART_EFR_ECB);
                serial_outp(up, UART_LCR, 0);
        }
@@ -2848,7 +2820,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 
        local_irq_save(flags);
        if (up->port.sysrq) {
-               /* serial8250_handle_port() already took the lock */
+               /* serial8250_handle_irq() already took the lock */
                locked = 0;
        } else if (oops_in_progress) {
                locked = spin_trylock(&up->port.lock);
@@ -2882,7 +2854,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
         *      while processing with interrupts off.
         */
        if (up->msr_saved_flags)
-               check_modem_status(up);
+               serial8250_modem_status(up);
 
        if (locked)
                spin_unlock(&up->port.lock);