Merge tag 'tty-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[linux-2.6-microblaze.git] / drivers / tty / serial / 8250 / 8250_port.c
index 3c36a06..39b35a6 100644 (file)
@@ -50,8 +50,6 @@
 #define DEBUG_AUTOCONF(fmt...) do { } while (0)
 #endif
 
-#define BOTH_EMPTY     (UART_LSR_TEMT | UART_LSR_THRE)
-
 /*
  * Here we define the default xmit fifo size used for each type of UART.
  */
@@ -336,27 +334,29 @@ static void default_serial_dl_write(struct uart_8250_port *up, int value)
 
 #ifdef CONFIG_SERIAL_8250_RT288X
 
+#define UART_REG_UNMAPPED      -1
+
 /* Au1x00/RT288x UART hardware has a weird register layout */
 static const s8 au_io_in_map[8] = {
-        0,     /* UART_RX  */
-        2,     /* UART_IER */
-        3,     /* UART_IIR */
-        5,     /* UART_LCR */
-        6,     /* UART_MCR */
-        7,     /* UART_LSR */
-        8,     /* UART_MSR */
-       -1,     /* UART_SCR (unmapped) */
+       [UART_RX]       = 0,
+       [UART_IER]      = 2,
+       [UART_IIR]      = 3,
+       [UART_LCR]      = 5,
+       [UART_MCR]      = 6,
+       [UART_LSR]      = 7,
+       [UART_MSR]      = 8,
+       [UART_SCR]      = UART_REG_UNMAPPED,
 };
 
 static const s8 au_io_out_map[8] = {
-        1,     /* UART_TX  */
-        2,     /* UART_IER */
-        4,     /* UART_FCR */
-        5,     /* UART_LCR */
-        6,     /* UART_MCR */
-       -1,     /* UART_LSR (unmapped) */
-       -1,     /* UART_MSR (unmapped) */
-       -1,     /* UART_SCR (unmapped) */
+       [UART_TX]       = 1,
+       [UART_IER]      = 2,
+       [UART_FCR]      = 4,
+       [UART_LCR]      = 5,
+       [UART_MCR]      = 6,
+       [UART_LSR]      = UART_REG_UNMAPPED,
+       [UART_MSR]      = UART_REG_UNMAPPED,
+       [UART_SCR]      = UART_REG_UNMAPPED,
 };
 
 unsigned int au_serial_in(struct uart_port *p, int offset)
@@ -364,7 +364,7 @@ unsigned int au_serial_in(struct uart_port *p, int offset)
        if (offset >= ARRAY_SIZE(au_io_in_map))
                return UINT_MAX;
        offset = au_io_in_map[offset];
-       if (offset < 0)
+       if (offset == UART_REG_UNMAPPED)
                return UINT_MAX;
        return __raw_readl(p->membase + (offset << p->regshift));
 }
@@ -374,7 +374,7 @@ void au_serial_out(struct uart_port *p, int offset, int value)
        if (offset >= ARRAY_SIZE(au_io_out_map))
                return;
        offset = au_io_out_map[offset];
-       if (offset < 0)
+       if (offset == UART_REG_UNMAPPED)
                return;
        __raw_writel(value, p->membase + (offset << p->regshift));
 }
@@ -647,6 +647,14 @@ void serial8250_em485_destroy(struct uart_8250_port *p)
 }
 EXPORT_SYMBOL_GPL(serial8250_em485_destroy);
 
+struct serial_rs485 serial8250_em485_supported = {
+       .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND |
+                SER_RS485_TERMINATE_BUS | SER_RS485_RX_DURING_TX,
+       .delay_rts_before_send = 1,
+       .delay_rts_after_send = 1,
+};
+EXPORT_SYMBOL_GPL(serial8250_em485_supported);
+
 /**
  * serial8250_em485_config() - generic ->rs485_config() callback
  * @port: uart port
@@ -656,7 +664,8 @@ EXPORT_SYMBOL_GPL(serial8250_em485_destroy);
  * if the uart is incapable of driving RTS as a Transmit Enable signal in
  * hardware, relying on software emulation instead.
  */
-int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485)
+int serial8250_em485_config(struct uart_port *port, struct ktermios *termios,
+                           struct serial_rs485 *rs485)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
 
@@ -667,29 +676,12 @@ int serial8250_em485_config(struct uart_port *port, struct serial_rs485 *rs485)
                rs485->flags &= ~SER_RS485_RTS_AFTER_SEND;
        }
 
-       /* clamp the delays to [0, 100ms] */
-       rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
-       rs485->delay_rts_after_send  = min(rs485->delay_rts_after_send, 100U);
-
-       memset(rs485->padding, 0, sizeof(rs485->padding));
-       port->rs485 = *rs485;
-
-       gpiod_set_value(port->rs485_term_gpio,
-                       rs485->flags & SER_RS485_TERMINATE_BUS);
-
        /*
         * Both serial8250_em485_init() and serial8250_em485_destroy()
         * are idempotent.
         */
-       if (rs485->flags & SER_RS485_ENABLED) {
-               int ret = serial8250_em485_init(up);
-
-               if (ret) {
-                       rs485->flags &= ~SER_RS485_ENABLED;
-                       port->rs485.flags &= ~SER_RS485_ENABLED;
-               }
-               return ret;
-       }
+       if (rs485->flags & SER_RS485_ENABLED)
+               return serial8250_em485_init(up);
 
        serial8250_em485_destroy(up);
        return 0;
@@ -849,7 +841,7 @@ static int size_fifo(struct uart_8250_port *up)
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        old_dl = serial_dl_read(up);
        serial_dl_write(up, 0x0001);
-       serial_out(up, UART_LCR, 0x03);
+       serial_out(up, UART_LCR, UART_LCR_WLEN8);
        for (count = 0; count < 256; count++)
                serial_out(up, UART_TX, count);
        mdelay(20);/* FIXME - schedule_timeout */
@@ -1503,18 +1495,12 @@ static void __stop_tx_rs485(struct uart_8250_port *p, u64 stop_delay)
        }
 }
 
-static inline void __do_stop_tx(struct uart_8250_port *p)
-{
-       if (serial8250_clear_THRI(p))
-               serial8250_rpm_put_tx(p);
-}
-
 static inline void __stop_tx(struct uart_8250_port *p)
 {
        struct uart_8250_em485 *em485 = p->em485;
 
        if (em485) {
-               unsigned char lsr = serial_in(p, UART_LSR);
+               u16 lsr = serial_lsr_in(p);
                u64 stop_delay = 0;
 
                p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
@@ -1522,7 +1508,7 @@ static inline void __stop_tx(struct uart_8250_port *p)
                if (!(lsr & UART_LSR_THRE))
                        return;
                /*
-                * To provide required timeing and allow FIFO transfer,
+                * To provide required timing and allow FIFO transfer,
                 * __stop_tx_rs485() must be called only when both FIFO and
                 * shift register are empty. The device driver should either
                 * enable interrupt on TEMT or set UART_CAP_NOTEMT that will
@@ -1544,7 +1530,9 @@ static inline void __stop_tx(struct uart_8250_port *p)
 
                __stop_tx_rs485(p, stop_delay);
        }
-       __do_stop_tx(p);
+
+       if (serial8250_clear_THRI(p))
+               serial8250_rpm_put_tx(p);
 }
 
 static void serial8250_stop_tx(struct uart_port *port)
@@ -1573,10 +1561,8 @@ static inline void __start_tx(struct uart_port *port)
 
        if (serial8250_set_THRI(up)) {
                if (up->bugs & UART_BUG_TXEN) {
-                       unsigned char lsr;
+                       u16 lsr = serial_lsr_in(up);
 
-                       lsr = serial_in(up, UART_LSR);
-                       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
                        if (lsr & UART_LSR_THRE)
                                serial8250_tx_chars(up);
                }
@@ -1616,7 +1602,8 @@ void serial8250_em485_start_tx(struct uart_8250_port *up)
 }
 EXPORT_SYMBOL_GPL(serial8250_em485_start_tx);
 
-static inline void start_tx_rs485(struct uart_port *port)
+/* Returns false, if start_tx_timer was setup to defer TX start */
+static bool start_tx_rs485(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        struct uart_8250_em485 *em485 = up->em485;
@@ -1644,11 +1631,11 @@ static inline void start_tx_rs485(struct uart_port *port)
                        em485->active_timer = &em485->start_tx_timer;
                        start_hrtimer_ms(&em485->start_tx_timer,
                                         up->port.rs485.delay_rts_before_send);
-                       return;
+                       return false;
                }
        }
 
-       __start_tx(port);
+       return true;
 }
 
 static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t)
@@ -1678,14 +1665,12 @@ static void serial8250_start_tx(struct uart_port *port)
 
        serial8250_rpm_get_tx(up);
 
-       if (em485 &&
-           em485->active_timer == &em485->start_tx_timer)
-               return;
-
-       if (em485)
-               start_tx_rs485(port);
-       else
-               __start_tx(port);
+       if (em485) {
+               if ((em485->active_timer == &em485->start_tx_timer) ||
+                   !start_tx_rs485(port))
+                       return;
+       }
+       __start_tx(port);
 }
 
 static void serial8250_throttle(struct uart_port *port)
@@ -1729,7 +1714,7 @@ static void serial8250_enable_ms(struct uart_port *port)
        serial8250_rpm_put(up);
 }
 
-void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
+void serial8250_read_char(struct uart_8250_port *up, u16 lsr)
 {
        struct uart_port *port = &up->port;
        unsigned char ch;
@@ -1792,11 +1777,13 @@ void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
 EXPORT_SYMBOL_GPL(serial8250_read_char);
 
 /*
- * serial8250_rx_chars: processes according to the passed in LSR
- * value, and returns the remaining LSR bits not handled
- * by this Rx routine.
+ * serial8250_rx_chars - Read characters. The first LSR value must be passed in.
+ *
+ * Returns LSR bits. The caller should rely only on non-Rx related LSR bits
+ * (such as THRE) because the LSR value might come from an already consumed
+ * character.
  */
-unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
+u16 serial8250_rx_chars(struct uart_8250_port *up, u16 lsr)
 {
        struct uart_port *port = &up->port;
        int max_count = 256;
@@ -1852,7 +1839,7 @@ void serial8250_tx_chars(struct uart_8250_port *up)
                if (uart_circ_empty(xmit))
                        break;
                if ((up->capabilities & UART_CAP_HFIFO) &&
-                   (serial_in(up, UART_LSR) & BOTH_EMPTY) != BOTH_EMPTY)
+                   !uart_lsr_tx_empty(serial_in(up, UART_LSR)))
                        break;
                /* The BCM2835 MINI UART THRE bit is really a not-full bit. */
                if ((up->capabilities & UART_CAP_MINI) &&
@@ -1916,17 +1903,17 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
  */
 int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 {
-       unsigned char status;
        struct uart_8250_port *up = up_to_u8250p(port);
        bool skip_rx = false;
        unsigned long flags;
+       u16 status;
 
        if (iir & UART_IIR_NO_INT)
                return 0;
 
        spin_lock_irqsave(&port->lock, flags);
 
-       status = serial_port_in(port, UART_LSR);
+       status = serial_lsr_in(up);
 
        /*
         * If port is stopped and there are no error conditions in the
@@ -2002,18 +1989,17 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        unsigned long flags;
-       unsigned int lsr;
+       u16 lsr;
 
        serial8250_rpm_get(up);
 
        spin_lock_irqsave(&port->lock, flags);
-       lsr = serial_port_in(port, UART_LSR);
-       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+       lsr = serial_lsr_in(up);
        spin_unlock_irqrestore(&port->lock, flags);
 
        serial8250_rpm_put(up);
 
-       return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
+       return uart_lsr_tx_empty(lsr) ? TIOCSER_TEMT : 0;
 }
 
 unsigned int serial8250_do_get_mctrl(struct uart_port *port)
@@ -2084,9 +2070,7 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits)
 
        /* Wait up to 10ms for the character(s) to be sent. */
        for (;;) {
-               status = serial_in(up, UART_LSR);
-
-               up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
+               status = serial_lsr_in(up);
 
                if ((status & bits) == bits)
                        break;
@@ -2128,8 +2112,8 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
 static int serial8250_get_poll_char(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
-       unsigned char lsr;
        int status;
+       u16 lsr;
 
        serial8250_rpm_get(up);
 
@@ -2163,7 +2147,7 @@ static void serial8250_put_poll_char(struct uart_port *port,
        else
                serial_port_out(port, UART_IER, 0);
 
-       wait_for_xmitr(up, BOTH_EMPTY);
+       wait_for_xmitr(up, UART_LSR_BOTH_EMPTY);
        /*
         *      Send the character out.
         */
@@ -2173,7 +2157,7 @@ static void serial8250_put_poll_char(struct uart_port *port,
         *      Finally, wait for transmitter to become empty
         *      and restore the IER
         */
-       wait_for_xmitr(up, BOTH_EMPTY);
+       wait_for_xmitr(up, UART_LSR_BOTH_EMPTY);
        serial_port_out(port, UART_IER, ier);
        serial8250_rpm_put(up);
 }
@@ -2184,8 +2168,9 @@ int serial8250_do_startup(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        unsigned long flags;
-       unsigned char lsr, iir;
+       unsigned char iir;
        int retval;
+       u16 lsr;
 
        if (!port->fifosize)
                port->fifosize = uart_config[port->type].fifo_size;
@@ -2810,7 +2795,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                port->read_status_mask |= UART_LSR_BI;
 
        /*
-        * Characteres to ignore
+        * Characters to ignore
         */
        port->ignore_status_mask = 0;
        if (termios->c_iflag & IGNPAR)
@@ -3203,7 +3188,7 @@ static void serial8250_config_port(struct uart_port *port, int flags)
                autoconfig(up);
 
        if (port->rs485.flags & SER_RS485_ENABLED)
-               port->rs485_config(port, &port->rs485);
+               uart_rs485_config(port);
 
        /* if access method is AU, it is a 16550 with a quirk */
        if (port->type == PORT_16550A && port->iotype == UPIO_AU)
@@ -3445,7 +3430,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
         *      Finally, wait for transmitter to become empty
         *      and restore the IER
         */
-       wait_for_xmitr(up, BOTH_EMPTY);
+       wait_for_xmitr(up, UART_LSR_BOTH_EMPTY);
 
        if (em485) {
                mdelay(port->rs485.delay_rts_after_send);