@@ -2199,6 +2199,54 @@ static void serial8250_set_TRG_levels(struct uart_port *port)
21992199 }
22002200}
22012201
2202+ static void serial8250_THRE_test (struct uart_port * port )
2203+ {
2204+ struct uart_8250_port * up = up_to_u8250p (port );
2205+ unsigned long flags ;
2206+ bool iir_noint1 , iir_noint2 ;
2207+
2208+ if (!port -> irq )
2209+ return ;
2210+
2211+ if (up -> port .flags & UPF_NO_THRE_TEST )
2212+ return ;
2213+
2214+ if (port -> irqflags & IRQF_SHARED )
2215+ disable_irq_nosync (port -> irq );
2216+
2217+ /*
2218+ * Test for UARTs that do not reassert THRE when the transmitter is idle and the interrupt
2219+ * has already been cleared. Real 16550s should always reassert this interrupt whenever the
2220+ * transmitter is idle and the interrupt is enabled. Delays are necessary to allow register
2221+ * changes to become visible.
2222+ *
2223+ * Synchronize UART_IER access against the console.
2224+ */
2225+ uart_port_lock_irqsave (port , & flags );
2226+
2227+ wait_for_xmitr (up , UART_LSR_THRE );
2228+ serial_port_out_sync (port , UART_IER , UART_IER_THRI );
2229+ udelay (1 ); /* allow THRE to set */
2230+ iir_noint1 = serial_port_in (port , UART_IIR ) & UART_IIR_NO_INT ;
2231+ serial_port_out (port , UART_IER , 0 );
2232+ serial_port_out_sync (port , UART_IER , UART_IER_THRI );
2233+ udelay (1 ); /* allow a working UART time to re-assert THRE */
2234+ iir_noint2 = serial_port_in (port , UART_IIR ) & UART_IIR_NO_INT ;
2235+ serial_port_out (port , UART_IER , 0 );
2236+
2237+ uart_port_unlock_irqrestore (port , flags );
2238+
2239+ if (port -> irqflags & IRQF_SHARED )
2240+ enable_irq (port -> irq );
2241+
2242+ /*
2243+ * If the interrupt is not reasserted, or we otherwise don't trust the iir, setup a timer to
2244+ * kick the UART on a regular basis.
2245+ */
2246+ if ((!iir_noint1 && iir_noint2 ) || up -> port .flags & UPF_BUG_THRE )
2247+ up -> bugs |= UART_BUG_THRE ;
2248+ }
2249+
22022250int serial8250_do_startup (struct uart_port * port )
22032251{
22042252 struct uart_8250_port * up = up_to_u8250p (port );
@@ -2258,49 +2306,7 @@ int serial8250_do_startup(struct uart_port *port)
22582306 if (retval )
22592307 goto out ;
22602308
2261- if (port -> irq && !(up -> port .flags & UPF_NO_THRE_TEST )) {
2262- unsigned char iir1 ;
2263-
2264- if (port -> irqflags & IRQF_SHARED )
2265- disable_irq_nosync (port -> irq );
2266-
2267- /*
2268- * Test for UARTs that do not reassert THRE when the
2269- * transmitter is idle and the interrupt has already
2270- * been cleared. Real 16550s should always reassert
2271- * this interrupt whenever the transmitter is idle and
2272- * the interrupt is enabled. Delays are necessary to
2273- * allow register changes to become visible.
2274- *
2275- * Synchronize UART_IER access against the console.
2276- */
2277- uart_port_lock_irqsave (port , & flags );
2278-
2279- wait_for_xmitr (up , UART_LSR_THRE );
2280- serial_port_out_sync (port , UART_IER , UART_IER_THRI );
2281- udelay (1 ); /* allow THRE to set */
2282- iir1 = serial_port_in (port , UART_IIR );
2283- serial_port_out (port , UART_IER , 0 );
2284- serial_port_out_sync (port , UART_IER , UART_IER_THRI );
2285- udelay (1 ); /* allow a working UART time to re-assert THRE */
2286- iir = serial_port_in (port , UART_IIR );
2287- serial_port_out (port , UART_IER , 0 );
2288-
2289- uart_port_unlock_irqrestore (port , flags );
2290-
2291- if (port -> irqflags & IRQF_SHARED )
2292- enable_irq (port -> irq );
2293-
2294- /*
2295- * If the interrupt is not reasserted, or we otherwise
2296- * don't trust the iir, setup a timer to kick the UART
2297- * on a regular basis.
2298- */
2299- if ((!(iir1 & UART_IIR_NO_INT ) && (iir & UART_IIR_NO_INT )) ||
2300- up -> port .flags & UPF_BUG_THRE ) {
2301- up -> bugs |= UART_BUG_THRE ;
2302- }
2303- }
2309+ serial8250_THRE_test (port );
23042310
23052311 up -> ops -> setup_timer (up );
23062312
0 commit comments