在 2023/4/14 20:10, Ilpo Järvinen 写道:
On Fri, 14 Apr 2023, qianfan wrote:
Hi:
My custom board is based on allwinner R40, the uart is compatibled with
serial8250. Based on it's datasheet:
When TX transmit data, or RX receives data, or TX FIFO is not empty, then
the
BUSY flag bit can be set to 1 by hardware, which indicates the UART
controller is busy.
We cannot write LCR and DLL to update UART params such as baudrate and partity
while the UART is busy, however `serial8250_do_set_termios` is a void
function,
the upper level always assume the uart params is updated.
The upper level `uart_set_termios` do noting if ktermios params is not
changed,
it will not update when the user space program running tcsetattr set a same
baudrate again.
So we can not fix the baudrate when
`serial8250_do_set_termios`
failed.
Allwinner R40's datasheet provided a way for this case.
CHCFG_AT_BUSY(configure at busy): Enable the bit, software can also set UART
controller when UART is busy, such as the LCR, DLH, DLL register.
CHANGE_UPDATE(change update): If CHCFG_AT_BUSY is enabled, and CHANGE_UPDATE
is written to 1, the configuration of UART controller can be updated.
After completed update, the bit is cleared to 0 automatically.
I can't know this feature is expanded by allwinner, or it is a common
functiton
of serial8250. Perhaps the serial8250 driver need this.
tcsetattr() can be given a flag which enforces TX empty condition before
core calls into the lower layer HW set_termios function. Would that be
enough to solve the case you're interested in?
Obviously, nothing can prevent Rx from occuring as it's not under local
UART's control (e.g. a busy flag check would still be racy). But does
writing those registers actually break something or just corrupts the
character under Tx/Rx (which can be handled by flushing)?
I think flushing can't resolv this problem. We can control the time to
sending
but can not control when we are recving.
The RX busy is always exists.