[PATCH] serial: 8250: Fix THRE flag usage for CAP_MINI

Phil Elwell phil at raspberrypi.org
Tue Jun 27 02:24:21 PDT 2017

On 27/06/2017 10:18, Andy Shevchenko wrote:
> On Mon, 2017-06-26 at 14:59 +0100, Phil Elwell wrote:
>> The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
>> the bit means that the FIFO is empty (although there may still be a
>> byte in the transmit register), but on 2835 it indicates that the FIFO
>> is not full. This causes interrupts after every byte is transmitted,
>> with the FIFO providing some interrupt latency tolerance.
>> A consequence of this difference is that the usual strategy of writing
>> multiple bytes into the TX FIFO after checking THRE once is unsafe.
>> In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
>> but the first since by then the FIFO is full.
>> There is an HFIFO ("Hidden FIFO") capability that causes the transmit
>> loop to terminate when both THRE and TEMT are set, i.e. when the TX
>> block is completely idle. This is unnecessarily cautious, potentially
>> causing gaps in transmission.
>> Add a new conditional to the transmit loop, predicated on CAP_MINI,
>> that exits when THRE is no longer set (the FIFO is full). This allows
>> the FIFO to fill quickly but subsequent writes are paced by the
>> transmission rate.
>>  		if ((up->capabilities & UART_CAP_HFIFO) &&
>>  		    (serial_in(up, UART_LSR) & BOTH_EMPTY) !=
>>  			break;
>> +		/* The BCM2835 MINI UART THRE bit is really a not-
>> full bit. */
>> +		if ((up->capabilities & UART_CAP_MINI) &&
>> +		    !(serial_in(up, UART_LSR) & UART_LSR_THRE))
>> +			break;
> Might this end up with two sequential read of LSR?

The same thought crossed my mind, but CAP_MINI is essentially CAP_BCM2835,
and we won't be setting CAP_HFIFO on BCM2835.

More information about the linux-rpi-kernel mailing list