[PATCH] serial imx.c: fix CTS trigger level lower to avoid lost chars

Russell King - ARM Linux linux at arm.linux.org.uk
Fri Jan 22 06:31:30 EST 2010


On Fri, Jan 22, 2010 at 11:07:01AM +0000, Jamie Lokier wrote:
> Valentin Longchamp wrote:
> > First I wanted to fix the fact that the imx serial hardware only raises 
> > the CTS pin when the oferflowing char begins to be set. I would have 
> > solved this by setting the CTS trigger value to 31 instead of 32. But 
> > when I talked with one colleague he told me about 16550A (that is 
> > present nearly everywhere) that empty their TX FIFO, so I lowered it to 16.
> 
> That seems quite peculiar because a 16550A only has a 16 byte receive
> buffer, doesn't it?  And therefore it would have trouble talking
> reliably to another 16550A if it worked like that.  I wonder what I'm
> not seeing in this picture.

What you're assuming is that flow control was there to prevent overruns
on the hardware receiver.  That's not the way it works on these devices;
flow control is entirely managed in software - there is no hardware
assistance.

The flow control implemented for non-FIFO and non-hardware assisted
UARTs is purely to do with preventing the software buffer behind the
UART from overflowing - it can't prevent the device's receiver buffering
from overrunning.  (Non-FIFO devices have the shift register and a
buffer register - complete reception of a second character before the
first is read causes an overrun condition.)

If you have overruns on the receiver, that's an interrupt latency
problem and its an error that's reported to the receiver side only.

Yes, later devices have the ability in hardware to deassert RTS when
the receiver FIFO gets above a certain threshold to /help/ prevent
overruns occuring when there's high interrupt latency - but normal
system operation should still ensure that the FIFO is emptied in a
timely manner.

They also gained the ability to stop the transmitter once CTS is
deasserted, mainly because the transmitter FIFOs in these devices
is soo large (maybe 32 to 128 bytes deep.)



More information about the linux-arm-kernel mailing list