diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 6b0f75eac8a2..c7d99af46a96 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -99,6 +99,7 @@ static void atmel_stop_rx(struct uart_port *port); #define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR) #define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR) #define UART_GET_IP_NAME(port) __raw_readl((port)->membase + ATMEL_US_NAME) +#define UART_GET_IP_VERSION(port) __raw_readl((port)->membase + ATMEL_US_VERSION) /* PDC registers */ #define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR) @@ -1503,6 +1504,7 @@ static void atmel_get_ip_name(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); int name = UART_GET_IP_NAME(port); + u32 version; int usart, uart; /* usart and uart ascii */ usart = 0x55534152; @@ -1517,7 +1519,22 @@ static void atmel_get_ip_name(struct uart_port *port) dev_dbg(port->dev, "This is uart\n"); atmel_port->is_usart = false; } else { - dev_err(port->dev, "Not supported ip name, set to uart\n"); + /* fallback for older SoCs: use version field */ + version = UART_GET_IP_VERSION(port); + switch (version) { + case 0x302: + case 0x10213: + dev_dbg(port->dev, "This version is usart\n"); + atmel_port->is_usart = true; + break; + case 0x203: + case 0x10202: + dev_dbg(port->dev, "This version is uart\n"); + atmel_port->is_usart = false; + break; + default: + dev_err(port->dev, "Not supported ip name nor version, set to uart\n"); + } } } diff --git a/include/linux/atmel_serial.h b/include/linux/atmel_serial.h index be201ca2990c..00beddf6be20 100644 --- a/include/linux/atmel_serial.h +++ b/include/linux/atmel_serial.h @@ -125,5 +125,6 @@ #define ATMEL_US_IF 0x4c /* IrDA Filter Register */ #define ATMEL_US_NAME 0xf0 /* Ip Name */ +#define ATMEL_US_VERSION 0xfc /* Ip Version */ #endif