@@ -1504,18 +1504,19 @@ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL);
}
-static void __stop_tx_rs485(struct uart_8250_port *p)
+static void __stop_tx_rs485(struct uart_8250_port *p, u64 stop_delay)
{
struct uart_8250_em485 *em485 = p->em485;
+ stop_delay += (u64)p->port.rs485.delay_rts_after_send * NSEC_PER_MSEC;
+
/*
* rs485_stop_tx() is going to set RTS according to config
* AND flush RX FIFO if required.
*/
- if (p->port.rs485.delay_rts_after_send > 0) {
+ if (stop_delay > 0) {
em485->active_timer = &em485->stop_tx_timer;
- start_hrtimer_ms(&em485->stop_tx_timer,
- p->port.rs485.delay_rts_after_send);
+ hrtimer_start(&em485->stop_tx_timer, ns_to_ktime(stop_delay), HRTIMER_MODE_REL);
} else {
p->rs485_stop_tx(p);
em485->active_timer = NULL;
@@ -1535,16 +1536,32 @@ static inline void __stop_tx(struct uart_8250_port *p)
if (em485) {
unsigned char lsr = serial_in(p, UART_LSR);
+ u64 stop_delay = 0;
+
+ if (!(lsr & UART_LSR_THRE))
+ return;
/*
* 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.
+ * shift register are empty. The device driver should either
+ * enable interrupt on TEMT or set UART_CAP_NOTEMT that will
+ * enlarge stop_tx_timer by the tx time of one frame to cover
+ * for emptying of the shift register.
*/
- if ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
- return;
+ if (!(lsr & UART_LSR_TEMT)) {
+ if (!(p->capabilities & UART_CAP_NOTEMT))
+ return;
+ /*
+ * RTS might get deasserted too early with the normal
+ * frame timing formula. It seems to suggest THRE might
+ * get asserted already during tx of the stop bit
+ * rather than after it is fully sent.
+ * Roughly estimate 1 extra bit here with / 7.
+ */
+ stop_delay = p->port.frame_time + DIV_ROUND_UP(p->port.frame_time, 7);
+ }
- __stop_tx_rs485(p);
+ __stop_tx_rs485(p, stop_delay);
}
__do_stop_tx(p);
}