Revert "serial: 8250: Handle UART without interrupt on TEMT using em485"
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Wed, 20 Apr 2022 08:19:01 +0000 (11:19 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Apr 2022 14:53:38 +0000 (16:53 +0200)
This partially reverts commit f6f586102add. The code added by
that commit containted math overflow for 32-bit archs. In
addition, the approach used in it is unnecessarily complicated
requiring a dedicated timer just for notemt. A simpler approach
for providing UART_CAP_NOTEMT already exists (patches 1-2):
  https://lore.kernel.org/linux-serial/20220411083321.9131-3-ilpo.jarvinen@linux.intel.com/T/#u
Thus, simply revert the UART_CAP_NOTEMT change for now.

There were two driver changes within the patch series adding
UART_CAP_NOTEMT taking advantage of the newly added flag.
This does not revert the driver changes and therefore also
UART_CAP_NOTEMT define has to remain. UART_CAP_NOTEMT remains
no-op until support is again added.

Fixes: f6f586102add ("serial: 8250: Handle UART without interrupt on TEMT using em485")
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/5f874142-fb1f-bff7-f33-fac823e65e2e@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_port.c
include/linux/serial_8250.h

index c1f24e88ef097cda820924b3a80cc0014699b483..33bd062140c9674e157db1d5fcf44e1c12d8d9c6 100644 (file)
@@ -571,21 +571,8 @@ static void serial8250_clear_fifos(struct uart_8250_port *p)
        }
 }
 
-static inline void serial8250_em485_update_temt_delay(struct uart_8250_port *p,
-                       unsigned int cflag, unsigned int baud)
-{
-       unsigned int bits;
-
-       if (!p->em485)
-               return;
-
-       bits = tty_get_frame_size(cflag);
-       p->em485->no_temt_delay = DIV_ROUND_UP(bits * NSEC_PER_SEC, baud);
-}
-
 static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t);
 static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t);
-static enum hrtimer_restart serial8250_em485_handle_no_temt(struct hrtimer *t);
 
 void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
 {
@@ -644,16 +631,6 @@ static int serial8250_em485_init(struct uart_8250_port *p)
                     HRTIMER_MODE_REL);
        hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC,
                     HRTIMER_MODE_REL);
-
-       if (p->capabilities & UART_CAP_NOTEMT) {
-               struct tty_struct *tty = p->port.state->port.tty;
-
-               serial8250_em485_update_temt_delay(p, tty->termios.c_cflag,
-                                                  tty_get_baud_rate(tty));
-               hrtimer_init(&p->em485->no_temt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-               p->em485->no_temt_timer.function = &serial8250_em485_handle_no_temt;
-       }
-
        p->em485->stop_tx_timer.function = &serial8250_em485_handle_stop_tx;
        p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx;
        p->em485->port = p;
@@ -685,7 +662,6 @@ void serial8250_em485_destroy(struct uart_8250_port *p)
 
        hrtimer_cancel(&p->em485->start_tx_timer);
        hrtimer_cancel(&p->em485->stop_tx_timer);
-       hrtimer_cancel(&p->em485->no_temt_timer);
 
        kfree(p->em485);
        p->em485 = NULL;
@@ -1528,11 +1504,6 @@ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
        hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL);
 }
 
-static void start_hrtimer_ns(struct hrtimer *hrt, unsigned long nsec)
-{
-       hrtimer_start(hrt, ns_to_ktime(nsec), HRTIMER_MODE_REL);
-}
-
 static void __stop_tx_rs485(struct uart_8250_port *p)
 {
        struct uart_8250_em485 *em485 = p->em485;
@@ -1564,33 +1535,14 @@ static inline void __stop_tx(struct uart_8250_port *p)
 
        if (em485) {
                unsigned char lsr = serial_in(p, UART_LSR);
-
-               p->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-
                /*
-                * To provide required timing and allow FIFO transfer,
+                * To provide required timeing and allow FIFO transfer,
                 * __stop_tx_rs485() must be called only when both FIFO and
                 * shift register are empty. It is for device driver to enable
                 * interrupt on TEMT.
                 */
-               if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) {
-                       if (!(p->capabilities & UART_CAP_NOTEMT))
-                               /* __stop_tx will be called again once TEMT triggers */
-                               return;
-
-                       if (!(lsr & UART_LSR_THRE))
-                               /* __stop_tx will be called again once THRE triggers */
-                               return;
-
-                       /*
-                        * On devices with no TEMT interrupt available, start
-                        * a timer for a byte time. The timer will recall
-                        * __stop_tx().
-                        */
-                       em485->active_timer = &em485->no_temt_timer;
-                       start_hrtimer_ns(&em485->no_temt_timer, em485->no_temt_delay);
+               if ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
                        return;
-               }
 
                __stop_tx_rs485(p);
        }
@@ -1701,27 +1653,6 @@ static inline void start_tx_rs485(struct uart_port *port)
        __start_tx(port);
 }
 
-static enum hrtimer_restart serial8250_em485_handle_no_temt(struct hrtimer *t)
-{
-       struct uart_8250_em485 *em485;
-       struct uart_8250_port *p;
-       unsigned long flags;
-
-       em485 = container_of(t, struct uart_8250_em485, no_temt_timer);
-       p = em485->port;
-
-       serial8250_rpm_get(p);
-       spin_lock_irqsave(&p->port.lock, flags);
-       if (em485->active_timer == &em485->no_temt_timer) {
-               em485->active_timer = NULL;
-               __stop_tx(p);
-       }
-
-       spin_unlock_irqrestore(&p->port.lock, flags);
-       serial8250_rpm_put(p);
-       return HRTIMER_NORESTART;
-}
-
 static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t)
 {
        struct uart_8250_em485 *em485 = container_of(t, struct uart_8250_em485,
@@ -2927,9 +2858,6 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 
        serial8250_set_divisor(port, baud, quot, frac);
 
-       if (up->capabilities & UART_CAP_NOTEMT)
-               serial8250_em485_update_temt_delay(up, termios->c_cflag, baud);
-
        /*
         * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
         * is written without DLAB set, this mode will be disabled.
index de135852107cb57bdf86b1d31bc1a0be362713f7..ff84a3ed10ea911c742978ba01863052d8d6a4ab 100644 (file)
@@ -79,9 +79,7 @@ struct uart_8250_ops {
 struct uart_8250_em485 {
        struct hrtimer          start_tx_timer; /* "rs485 start tx" timer */
        struct hrtimer          stop_tx_timer;  /* "rs485 stop tx" timer */
-       struct hrtimer          no_temt_timer;  /* "rs485 no TEMT interrupt" timer */
        struct hrtimer          *active_timer;  /* pointer to active timer */
-       unsigned long           no_temt_delay;  /* Delay for no_temt_timer */
        struct uart_8250_port   *port;          /* for hrtimer callbacks */
        unsigned int            tx_stopped:1;   /* tx is currently stopped */
 };