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.