I have done some modifications on the Linux QUICC Engine UART device driver (ucc_uart.c) to control the DRT bit in UPSMR. During this work I found some code that has to be wrong. The problem is in qe_uart_set_termios() where all but the byte size part of UPSMR is cleared while I think the purpose was to clear only the byte size part. The result is that setting byte size isn't working correct. Most peaple are using 8 bit byte size and this is working, so I guess this is why this bug hasn't been found before. Switching from 8 bit to any other will fail.
Below is my suggestion on how to fix it.
--- clean_linux/linux/drivers/tty/serial/ucc_uart.c
+++ linux/drivers/tty/serial/ucc_uart.c
@@ -880,8 +885,8 @@
*/
/* byte size */
- upsmr &= UCC_UART_UPSMR_CL_MASK;
- supsmr &= UCC_UART_SUPSMR_CL_MASK;
+ upsmr &= ~(UCC_UART_UPSMR_CL_MASK);
+ supsmr &= ~(UCC_UART_SUPSMR_CL_MASK);
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -911,6 +916,9 @@
upsmr |= UCC_UART_UPSMR_SL;
supsmr |= UCC_UART_SUPSMR_SL;
char_length++; /* + SL */
+ } else {
+ upsmr &= ~(UCC_UART_UPSMR_SL);
+ supsmr &= ~(UCC_UART_SUPSMR_SL);
}
if (termios->c_cflag & PARENB) {
@@ -928,6 +936,9 @@
supsmr |= UCC_UART_SUPSMR_RPM_EVEN |
UCC_UART_SUPSMR_TPM_EVEN;
}
+ } else {
+ upsmr &= ~(UCC_UART_UPSMR_PEN);
+ supsmr &= ~(UCC_UART_SUPSMR_PEN);
}
/*