[SERIAL] 8250: add tsi108 serial support

The following patch gets rid of CONFIG_TSI108_BRIDGE. I add UPIO_TSI to
handle IIR and IER register in serial_in and serial_out.

(1) the reason to rewrite serial_in:

TSI108 rev Z1 version ERRATA. Reading the UART's Interrupt
Identification Register (IIR) clears the Transmit Holding Register
Empty (THRE) and Transmit buffer Empty (TEMP) interrupts even if they
are not enabled in the Interrupt Enable Register (IER). This leads to
loss of the interrupts. Interrupts are not cleared when reading UART
registers as 32-bit word.

(2) the reason to rewrite serial_out:

Check for UART_IER_UUE bit in the autoconfig routine. This section
of autoconfig is excluded for Tsi108/109 because bits 7 and 6 are
reserved for internal use. They are R/W bits. In addition to
incorrect identification, changing these bits (from 00) will make
Tsi108/109 UART non-functional.

Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Zang Roy-r61911 and committed by Russell King 3be91ec7 c65b15cf

+14
+12
drivers/serial/8250.c
··· 299 300 static unsigned int serial_in(struct uart_8250_port *up, int offset) 301 { 302 offset = map_8250_in_reg(up, offset) << up->port.regshift; 303 304 switch (up->port.iotype) { ··· 317 case UPIO_AU: 318 return __raw_readl(up->port.membase + offset); 319 #endif 320 321 default: 322 return inb(up->port.iobase + offset); ··· 354 __raw_writel(value, up->port.membase + offset); 355 break; 356 #endif 357 358 default: 359 outb(value, up->port.iobase + offset);
··· 299 300 static unsigned int serial_in(struct uart_8250_port *up, int offset) 301 { 302 + unsigned int tmp; 303 offset = map_8250_in_reg(up, offset) << up->port.regshift; 304 305 switch (up->port.iotype) { ··· 316 case UPIO_AU: 317 return __raw_readl(up->port.membase + offset); 318 #endif 319 + 320 + case UPIO_TSI: 321 + if (offset == UART_IIR) { 322 + tmp = readl((u32 *)(up->port.membase + UART_RX)); 323 + return (cpu_to_le32(tmp) >> 8) & 0xff; 324 + } else 325 + return readb(up->port.membase + offset); 326 327 default: 328 return inb(up->port.iobase + offset); ··· 346 __raw_writel(value, up->port.membase + offset); 347 break; 348 #endif 349 + case UPIO_TSI: 350 + if (!((offset == UART_IER) && (value & UART_IER_UUE))) 351 + writeb(value, up->port.membase + offset); 352 + break; 353 354 default: 355 outb(value, up->port.iobase + offset);
+1
drivers/serial/serial_core.c
··· 2036 case UPIO_MEM: 2037 case UPIO_MEM32: 2038 case UPIO_AU: 2039 snprintf(address, sizeof(address), 2040 "MMIO 0x%lx", port->mapbase); 2041 break;
··· 2036 case UPIO_MEM: 2037 case UPIO_MEM32: 2038 case UPIO_AU: 2039 + case UPIO_TSI: 2040 snprintf(address, sizeof(address), 2041 "MMIO 0x%lx", port->mapbase); 2042 break;
+1
include/linux/serial_core.h
··· 227 #define UPIO_MEM (2) 228 #define UPIO_MEM32 (3) 229 #define UPIO_AU (4) /* Au1x00 type IO */ 230 231 unsigned int read_status_mask; /* driver specific */ 232 unsigned int ignore_status_mask; /* driver specific */
··· 227 #define UPIO_MEM (2) 228 #define UPIO_MEM32 (3) 229 #define UPIO_AU (4) /* Au1x00 type IO */ 230 + #define UPIO_TSI (5) /* Tsi108/109 type IO */ 231 232 unsigned int read_status_mask; /* driver specific */ 233 unsigned int ignore_status_mask; /* driver specific */