Skip to content

Commit a194597

Browse files
Jiri Slaby (SUSE)gregkh
authored andcommitted
serial: 8250: extract serial8250_THRE_test()
serial8250_do_startup() contains a stand-alone code for probing THRE. Furthermore, the code block is conditional (port->irq and test for UPF_NO_THRE_TEST). Move this code to a separate function. The conditional can be evaluated easier there -- by a simple return in the beginning. So the indentation level lowers and the code is overall more readable now. Signed-off-by: "Jiri Slaby (SUSE)" <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent cc85268 commit a194597

File tree

1 file changed

+49
-43
lines changed

1 file changed

+49
-43
lines changed

drivers/tty/serial/8250/8250_port.c

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
22022250
int 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

Comments
 (0)