Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: 8250: Add CAP_MINI, set for bcm2835aux

The AUX/mini-UART in the BCM2835 family of procesors is a cut-down
8250 clone. In particular it is lacking support for the following
features: CSTOPB PARENB PARODD CMSPAR CS5 CS6

Add a new capability (UART_CAP_MINI) that exposes the restrictions to
the user of the termios API by turning off the unsupported features in
the request.

N.B. It is almost possible to automatically discover the missing
features by reading back the LCR register, but the CSIZE bits don't
cooperate (contrary to the documentation, both bits are significant,
but CS5 and CS6 are mapped to CS7) and the code is much longer.

See: https://github.com/raspberrypi/linux/issues/1561

Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Phil Elwell and committed by
Greg Kroah-Hartman
d087e7a9 9b7becf1

+10 -1
+3
drivers/tty/serial/8250/8250.h
··· 81 81 #define UART_CAP_HFIFO (1 << 14) /* UART has a "hidden" FIFO */ 82 82 #define UART_CAP_RPM (1 << 15) /* Runtime PM is active while idle */ 83 83 #define UART_CAP_IRDA (1 << 16) /* UART supports IrDA line discipline */ 84 + #define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks: 85 + * STOP PARITY EPAR SPAR WLEN5 WLEN6 86 + */ 84 87 85 88 #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ 86 89 #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
+1 -1
drivers/tty/serial/8250/8250_bcm2835aux.c
··· 39 39 40 40 /* initialize data */ 41 41 spin_lock_init(&data->uart.port.lock); 42 - data->uart.capabilities = UART_CAP_FIFO; 42 + data->uart.capabilities = UART_CAP_FIFO | UART_CAP_MINI; 43 43 data->uart.port.dev = &pdev->dev; 44 44 data->uart.port.regshift = 2; 45 45 data->uart.port.type = PORT_16550;
+6
drivers/tty/serial/8250/8250_port.c
··· 2584 2584 unsigned long flags; 2585 2585 unsigned int baud, quot, frac = 0; 2586 2586 2587 + if (up->capabilities & UART_CAP_MINI) { 2588 + termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR); 2589 + if ((termios->c_cflag & CSIZE) == CS5 || 2590 + (termios->c_cflag & CSIZE) == CS6) 2591 + termios->c_cflag = (termios->c_cflag & ~CSIZE) | CS7; 2592 + } 2587 2593 cval = serial8250_compute_lcr(up, termios->c_cflag); 2588 2594 2589 2595 baud = serial8250_get_baud_rate(port, termios, old);